1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.commons.jcs3.io;
20
21 import java.io.IOException;
22 import java.io.InputStream;
23 import java.io.ObjectInputStream;
24 import java.io.ObjectStreamClass;
25 import java.lang.reflect.Proxy;
26
27 public class ObjectInputStreamClassLoaderAware extends ObjectInputStream {
28 private final ClassLoader classLoader;
29
30 public ObjectInputStreamClassLoaderAware(final InputStream in, final ClassLoader classLoader) throws IOException {
31 super(in);
32 this.classLoader = classLoader != null ? classLoader : Thread.currentThread().getContextClassLoader();
33 }
34
35 @Override
36 protected Class<?> resolveClass(final ObjectStreamClass desc) throws ClassNotFoundException {
37 return Class.forName(BlacklistClassResolver.DEFAULT.check(desc.getName()), false, classLoader);
38 }
39
40 @Override
41 protected Class<?> resolveProxyClass(final String[] interfaces) throws IOException, ClassNotFoundException {
42 final Class<?>[] cinterfaces = new Class[interfaces.length];
43 for (int i = 0; i < interfaces.length; i++) {
44 cinterfaces[i] = Class.forName(interfaces[i], false, classLoader);
45 }
46
47 try {
48 return Proxy.getProxyClass(classLoader, cinterfaces);
49 } catch (final IllegalArgumentException e) {
50 throw new ClassNotFoundException(null, e);
51 }
52 }
53
54 private static class BlacklistClassResolver {
55 private static final BlacklistClassResolver DEFAULT = new BlacklistClassResolver(
56 toArray(System.getProperty(
57 "jcs.serialization.class.blacklist",
58 "org.codehaus.groovy.runtime.,org.apache.commons.collections.functors.,org.apache.xalan")),
59 toArray(System.getProperty("jcs.serialization.class.whitelist")));
60
61 private final String[] blacklist;
62 private final String[] whitelist;
63
64 protected BlacklistClassResolver(final String[] blacklist, final String[] whitelist) {
65 this.whitelist = whitelist;
66 this.blacklist = blacklist;
67 }
68
69 protected boolean isBlacklisted(final String name) {
70 return whitelist != null && !contains(whitelist, name) || contains(blacklist, name);
71 }
72
73 public final String check(final String name) {
74 if (isBlacklisted(name)) {
75 throw new SecurityException(name + " is not whitelisted as deserialisable, prevented before loading.");
76 }
77 return name;
78 }
79
80 private static String[] toArray(final String property) {
81 return property == null ? null : property.split(" *, *");
82 }
83
84 private static boolean contains(final String[] list, final String name) {
85 if (list != null) {
86 for (final String white : list) {
87 if (name.startsWith(white)) {
88 return true;
89 }
90 }
91 }
92 return false;
93 }
94 }
95 }