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
|