src/share/classes/sun/rmi/server/MarshalInputStream.java

Print this page




  48  *
  49  * A new MarshalInputStream should be created to deserialize remote objects or
  50  * graphs containing remote objects.  Objects are created from the stream
  51  * using the ObjectInputStream.readObject method.
  52  *
  53  * @author      Peter Jones
  54  */
  55 public class MarshalInputStream extends ObjectInputStream {
  56 
  57     /**
  58      * value of "java.rmi.server.useCodebaseOnly" property,
  59      * as cached at class initialization time.
  60      */
  61     private static final boolean useCodebaseOnlyProperty =
  62         java.security.AccessController.doPrivileged(
  63             new sun.security.action.GetBooleanAction(
  64                 "java.rmi.server.useCodebaseOnly")).booleanValue();
  65 
  66     /** table to hold sun classes to which access is explicitly permitted */
  67     protected static Map<String, Class<?>> permittedSunClasses
  68         = new HashMap<String, Class<?>>(3);
  69 
  70     /** if true, don't try superclass first in resolveClass() */
  71     private boolean skipDefaultResolveClass = false;
  72 
  73     /** callbacks to make when done() called: maps Object to Runnable */
  74     private final Map<Object, Runnable> doneCallbacks
  75         = new HashMap<Object, Runnable>(3);
  76 
  77     /**
  78      * if true, load classes (if not available locally) only from the
  79      * URL specified by the "java.rmi.server.codebase" property.
  80      */
  81     private boolean useCodebaseOnly = useCodebaseOnlyProperty;
  82 
  83     /*
  84      * Fix for 4179055: The remote object services inside the
  85      * activation daemon use stubs that are in the package
  86      * sun.rmi.server.  Classes for these stubs should be loaded from
  87      * the classpath by RMI system code and not by the normal
  88      * unmarshalling process as applications should not need to have
  89      * permission to access the sun implementation classes.
  90      *
  91      * Note: this fix should be redone when API changes may be
  92      * integrated
  93      *
  94      * During parameter unmarshalling RMI needs to explicitly permit
  95      * access to three sun.* stub classes


 151         while (iter.hasNext()) {                        // not thread-safe
 152             Runnable callback = iter.next();
 153             callback.run();
 154         }
 155         doneCallbacks.clear();
 156     }
 157 
 158     /**
 159      * Closes this stream, implicitly invoking done() first.
 160      */
 161     public void close() throws IOException {
 162         done();
 163         super.close();
 164     }
 165 
 166     /**
 167      * resolveClass is extended to acquire (if present) the location
 168      * from which to load the specified class.
 169      * It will find, load, and return the class.
 170      */
 171     protected Class resolveClass(ObjectStreamClass classDesc)
 172         throws IOException, ClassNotFoundException
 173     {
 174         /*
 175          * Always read annotation written by MarshalOutputStream
 176          * describing where to load class from.
 177          */
 178         Object annotation = readLocation();
 179 
 180         String className = classDesc.getName();
 181 
 182         /*
 183          * Unless we were told to skip this consideration, choose the
 184          * "default loader" to simulate the default ObjectInputStream
 185          * resolveClass mechanism (that is, choose the first non-null
 186          * loader on the execution stack) to maximize the likelihood of
 187          * type compatibility with calling code.  (This consideration
 188          * is skipped during server parameter unmarshalling using the 1.2
 189          * stub protocol, because there would never be a non-null class
 190          * loader on the stack in that situation anyway.)
 191          */


 213             /*
 214              * Fix for 4442373: delegate to ObjectInputStream.resolveClass()
 215              * to resolve primitive classes.
 216              */
 217             try {
 218                 if (Character.isLowerCase(className.charAt(0)) &&
 219                     className.indexOf('.') == -1)
 220                 {
 221                     return super.resolveClass(classDesc);
 222                 }
 223             } catch (ClassNotFoundException e2) {
 224             }
 225             throw e;
 226         }
 227     }
 228 
 229     /**
 230      * resolveProxyClass is extended to acquire (if present) the location
 231      * to determine the class loader to define the proxy class in.
 232      */
 233     protected Class resolveProxyClass(String[] interfaces)
 234         throws IOException, ClassNotFoundException
 235     {
 236         /*
 237          * Always read annotation written by MarshalOutputStream.
 238          */
 239         Object annotation = readLocation();
 240 
 241         ClassLoader defaultLoader =
 242             skipDefaultResolveClass ? null : latestUserDefinedLoader();
 243 
 244         String codebase = null;
 245         if (!useCodebaseOnly && annotation instanceof String) {
 246             codebase = (String) annotation;
 247         }
 248 
 249         return RMIClassLoader.loadProxyClass(codebase, interfaces,
 250                                              defaultLoader);
 251     }
 252 
 253     /*
 254      * Returns the first non-null class loader up the execution stack, or null
 255      * if only code from the null class loader is on the stack.
 256      */
 257     private static ClassLoader latestUserDefinedLoader() {
 258         return sun.misc.VM.latestUserDefinedLoader();
 259     }
 260 
 261     /**
 262      * Fix for 4179055: Need to assist resolving sun stubs; resolve
 263      * class locally if it is a "permitted" sun class
 264      */
 265     private Class checkSunClass(String className, AccessControlException e)
 266         throws AccessControlException
 267     {
 268         // ensure that we are giving out a stub for the correct reason
 269         Permission perm = e.getPermission();
 270         String name = null;
 271         if (perm != null) {
 272             name = perm.getName();
 273         }
 274 
 275         Class<?> resolvedClass = permittedSunClasses.get(className);
 276 
 277         // if class not permitted, throw the SecurityException
 278         if ((name == null) ||
 279             (resolvedClass == null) ||
 280             ((!name.equals("accessClassInPackage.sun.rmi.server")) &&
 281             (!name.equals("accessClassInPackage.sun.rmi.registry"))))
 282         {
 283             throw e;
 284         }
 285 




  48  *
  49  * A new MarshalInputStream should be created to deserialize remote objects or
  50  * graphs containing remote objects.  Objects are created from the stream
  51  * using the ObjectInputStream.readObject method.
  52  *
  53  * @author      Peter Jones
  54  */
  55 public class MarshalInputStream extends ObjectInputStream {
  56 
  57     /**
  58      * value of "java.rmi.server.useCodebaseOnly" property,
  59      * as cached at class initialization time.
  60      */
  61     private static final boolean useCodebaseOnlyProperty =
  62         java.security.AccessController.doPrivileged(
  63             new sun.security.action.GetBooleanAction(
  64                 "java.rmi.server.useCodebaseOnly")).booleanValue();
  65 
  66     /** table to hold sun classes to which access is explicitly permitted */
  67     protected static Map<String, Class<?>> permittedSunClasses
  68         = new HashMap<>(3);
  69 
  70     /** if true, don't try superclass first in resolveClass() */
  71     private boolean skipDefaultResolveClass = false;
  72 
  73     /** callbacks to make when done() called: maps Object to Runnable */
  74     private final Map<Object, Runnable> doneCallbacks
  75         = new HashMap<>(3);
  76 
  77     /**
  78      * if true, load classes (if not available locally) only from the
  79      * URL specified by the "java.rmi.server.codebase" property.
  80      */
  81     private boolean useCodebaseOnly = useCodebaseOnlyProperty;
  82 
  83     /*
  84      * Fix for 4179055: The remote object services inside the
  85      * activation daemon use stubs that are in the package
  86      * sun.rmi.server.  Classes for these stubs should be loaded from
  87      * the classpath by RMI system code and not by the normal
  88      * unmarshalling process as applications should not need to have
  89      * permission to access the sun implementation classes.
  90      *
  91      * Note: this fix should be redone when API changes may be
  92      * integrated
  93      *
  94      * During parameter unmarshalling RMI needs to explicitly permit
  95      * access to three sun.* stub classes


 151         while (iter.hasNext()) {                        // not thread-safe
 152             Runnable callback = iter.next();
 153             callback.run();
 154         }
 155         doneCallbacks.clear();
 156     }
 157 
 158     /**
 159      * Closes this stream, implicitly invoking done() first.
 160      */
 161     public void close() throws IOException {
 162         done();
 163         super.close();
 164     }
 165 
 166     /**
 167      * resolveClass is extended to acquire (if present) the location
 168      * from which to load the specified class.
 169      * It will find, load, and return the class.
 170      */
 171     protected Class<?> resolveClass(ObjectStreamClass classDesc)
 172         throws IOException, ClassNotFoundException
 173     {
 174         /*
 175          * Always read annotation written by MarshalOutputStream
 176          * describing where to load class from.
 177          */
 178         Object annotation = readLocation();
 179 
 180         String className = classDesc.getName();
 181 
 182         /*
 183          * Unless we were told to skip this consideration, choose the
 184          * "default loader" to simulate the default ObjectInputStream
 185          * resolveClass mechanism (that is, choose the first non-null
 186          * loader on the execution stack) to maximize the likelihood of
 187          * type compatibility with calling code.  (This consideration
 188          * is skipped during server parameter unmarshalling using the 1.2
 189          * stub protocol, because there would never be a non-null class
 190          * loader on the stack in that situation anyway.)
 191          */


 213             /*
 214              * Fix for 4442373: delegate to ObjectInputStream.resolveClass()
 215              * to resolve primitive classes.
 216              */
 217             try {
 218                 if (Character.isLowerCase(className.charAt(0)) &&
 219                     className.indexOf('.') == -1)
 220                 {
 221                     return super.resolveClass(classDesc);
 222                 }
 223             } catch (ClassNotFoundException e2) {
 224             }
 225             throw e;
 226         }
 227     }
 228 
 229     /**
 230      * resolveProxyClass is extended to acquire (if present) the location
 231      * to determine the class loader to define the proxy class in.
 232      */
 233     protected Class<?> resolveProxyClass(String[] interfaces)
 234         throws IOException, ClassNotFoundException
 235     {
 236         /*
 237          * Always read annotation written by MarshalOutputStream.
 238          */
 239         Object annotation = readLocation();
 240 
 241         ClassLoader defaultLoader =
 242             skipDefaultResolveClass ? null : latestUserDefinedLoader();
 243 
 244         String codebase = null;
 245         if (!useCodebaseOnly && annotation instanceof String) {
 246             codebase = (String) annotation;
 247         }
 248 
 249         return RMIClassLoader.loadProxyClass(codebase, interfaces,
 250                                              defaultLoader);
 251     }
 252 
 253     /*
 254      * Returns the first non-null class loader up the execution stack, or null
 255      * if only code from the null class loader is on the stack.
 256      */
 257     private static ClassLoader latestUserDefinedLoader() {
 258         return sun.misc.VM.latestUserDefinedLoader();
 259     }
 260 
 261     /**
 262      * Fix for 4179055: Need to assist resolving sun stubs; resolve
 263      * class locally if it is a "permitted" sun class
 264      */
 265     private Class<?> checkSunClass(String className, AccessControlException e)
 266         throws AccessControlException
 267     {
 268         // ensure that we are giving out a stub for the correct reason
 269         Permission perm = e.getPermission();
 270         String name = null;
 271         if (perm != null) {
 272             name = perm.getName();
 273         }
 274 
 275         Class<?> resolvedClass = permittedSunClasses.get(className);
 276 
 277         // if class not permitted, throw the SecurityException
 278         if ((name == null) ||
 279             (resolvedClass == null) ||
 280             ((!name.equals("accessClassInPackage.sun.rmi.server")) &&
 281             (!name.equals("accessClassInPackage.sun.rmi.registry"))))
 282         {
 283             throw e;
 284         }
 285