001
014
015 package com.liferay.portal.security.pacl.checker;
016
017 import com.liferay.portal.kernel.log.Log;
018 import com.liferay.portal.kernel.log.LogFactoryUtil;
019 import com.liferay.portal.kernel.messaging.config.AbstractMessagingConfigurator;
020 import com.liferay.portal.kernel.security.pacl.permission.CheckMemberAccessPermission;
021 import com.liferay.portal.kernel.util.JavaDetector;
022 import com.liferay.portal.kernel.util.PathUtil;
023 import com.liferay.portal.kernel.util.ReferenceEntry;
024 import com.liferay.portal.kernel.util.ReferenceRegistry;
025 import com.liferay.portal.kernel.util.ServerDetector;
026 import com.liferay.portal.security.pacl.PACLClassLoaderUtil;
027 import com.liferay.portal.security.pacl.PACLClassUtil;
028
029 import java.beans.Introspector;
030
031 import java.security.Permission;
032
033 import jodd.util.ReflectUtil;
034
035 import org.hibernate.property.BasicPropertyAccessor;
036 import org.hibernate.tuple.entity.EntityTuplizerFactory;
037 import org.hibernate.util.ReflectHelper;
038
039 import org.springframework.beans.BeanUtils;
040 import org.springframework.beans.factory.support.SimpleInstantiationStrategy;
041 import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
042 import org.springframework.util.ReflectionUtils;
043
044 import sun.reflect.Reflection;
045
046
051 public abstract class BaseReflectChecker extends BaseChecker {
052
053 protected boolean hasReflect(Permission permission) {
054
055
059
060
061
062 String name = permission.getName();
063 String actions = permission.getActions();
064
065 if (isJSPCompiler(name, actions)) {
066 return true;
067 }
068
069 Class<?> callerClass9 = null;
070
071 if (permission instanceof CheckMemberAccessPermission) {
072 CheckMemberAccessPermission checkMemberAccessPermission =
073 (CheckMemberAccessPermission)permission;
074
075 if (checkMemberAccessPermission.getCallerClass() ==
076 ReferenceRegistry.class) {
077
078 Class<?> checkMemberAccessPermissionCallerClass =
079 checkMemberAccessPermission.getCallerClass();
080
081 int depth = 9;
082
083 while (checkMemberAccessPermissionCallerClass ==
084 ReferenceRegistry.class) {
085
086 depth++;
087
088 checkMemberAccessPermissionCallerClass =
089 Reflection.getCallerClass(depth);
090 }
091
092 ClassLoader callerClassLoader =
093 PACLClassLoaderUtil.getClassLoader(
094 checkMemberAccessPermissionCallerClass);
095
096 if (callerClassLoader ==
097 checkMemberAccessPermission.getSubjectClassLoader()) {
098
099 logReflect(checkMemberAccessPermissionCallerClass, depth);
100
101 return true;
102 }
103 }
104
105 callerClass9 = checkMemberAccessPermission.getCallerClass();
106 }
107 else {
108 callerClass9 = Reflection.getCallerClass(9);
109 }
110
111
112
113 if (isResinReflectionAnnotatedType(callerClass9)) {
114 logReflect(callerClass9, 9);
115
116 return true;
117 }
118
119
120
121 if (isResinJavaSessionSerializer()) {
122 return true;
123 }
124
125
126
127
128 if (callerClass9 == AbstractMessagingConfigurator.class) {
129 logReflect(callerClass9, 9);
130
131 return true;
132 }
133
134
135
136
137 if ((callerClass9.getEnclosingClass() == Introspector.class) &&
138 CheckerUtil.isAccessControllerDoPrivileged(10)) {
139
140 logReflect(callerClass9, 9);
141
142 return true;
143 }
144
145
146
147
148 if (callerClass9 == ReflectUtil.class) {
149 logReflect(callerClass9, 9);
150
151 return true;
152 }
153
154
155
156 Class<?> callerClass7 = Reflection.getCallerClass(7);
157 Class<?> callerClass8 = Reflection.getCallerClass(8);
158
159 if (name.equals("suppressAccessChecks") &&
160 (callerClass7 == ReferenceEntry.class)) {
161
162 if (callerClass8 == ReferenceRegistry.class) {
163 logReflect(callerClass7, 7);
164
165 return true;
166 }
167 }
168
169 if (JavaDetector.isIBM() || JavaDetector.isJDK7()) {
170 if ((callerClass8.getEnclosingClass() == Class.class) &&
171 CheckerUtil.isAccessControllerDoPrivileged(9)) {
172
173 logReflect(callerClass8, 8);
174
175 return true;
176 }
177 }
178 else {
179 if ((callerClass7.getEnclosingClass() == Class.class) &&
180 CheckerUtil.isAccessControllerDoPrivileged(8)) {
181
182 logReflect(callerClass7, 7);
183
184 return true;
185 }
186 }
187
188
189
190 if (JavaDetector.isJDK7() || JavaDetector.isOpenJDK()) {
191 Class<?> callerClass10 = Reflection.getCallerClass(10);
192
193 if ((callerClass10.getEnclosingClass() == Thread.class) &&
194 CheckerUtil.isAccessControllerDoPrivileged(11)) {
195
196 logReflect(callerClass10, 10);
197
198 return true;
199 }
200 }
201 else {
202 if ((callerClass9.getEnclosingClass() == Thread.class) &&
203 CheckerUtil.isAccessControllerDoPrivileged(10)) {
204
205 logReflect(callerClass9, 9);
206
207 return true;
208 }
209 }
210
211
212
213 if (isGlassfishSecureAction(
214 callerClass7.getEnclosingClass()) &&
215 CheckerUtil.isAccessControllerDoPrivileged(8)) {
216
217 logReflect(callerClass7, 7);
218
219 return true;
220 }
221
222
223
224 if (callerClass9 == BasicPropertyAccessor.class) {
225 logReflect(callerClass9, 9);
226
227 return true;
228 }
229
230
231
232 if (callerClass7 == EntityTuplizerFactory.class) {
233 logReflect(callerClass7, 7);
234
235 return true;
236 }
237
238
239
240 if (callerClass9 == ReflectHelper.class) {
241 logReflect(callerClass9, 9);
242
243 return true;
244 }
245
246
247
248 if (callerClass9 == BeanUtils.class) {
249 logReflect(callerClass9, 9);
250
251 return true;
252 }
253
254
255
256 if (callerClass9.getEnclosingClass() ==
257 SimpleInstantiationStrategy.class) {
258
259 logReflect(callerClass9, 9);
260
261 return true;
262 }
263
264
265
266 if (callerClass9.getEnclosingClass() ==
267 LocalVariableTableParameterNameDiscoverer.class) {
268
269 logReflect(callerClass9, 9);
270
271 return true;
272 }
273
274
275
276 if (callerClass7 == ReflectionUtils.class) {
277 logReflect(callerClass7, 7);
278
279 return true;
280 }
281
282 if (callerClass9 == ReflectionUtils.class) {
283 logReflect(callerClass9, 9);
284
285 return true;
286 }
287
288
289
290 if (isWebLogicAbstractApplicationContextDelegator(callerClass9)) {
291 logReflect(callerClass9, 9);
292
293 return true;
294 }
295
296
297
298 if (isWebLogicAbstractBeanDefinitionDelegator(callerClass9)) {
299 logReflect(callerClass9, 9);
300
301 return true;
302 }
303
304
305
306 if (_log.isDebugEnabled()) {
307 _log.debug("Rejecting call stack:");
308
309 for (int i = 6; i < 11; i++) {
310 _log.debug("Frame " + i + " " + Reflection.getCallerClass(i));
311 }
312 }
313
314 return false;
315 }
316
317 protected boolean isGlassfishSecureAction(Class<?> clazz) {
318 if (!ServerDetector.isGlassfish()) {
319 return false;
320 }
321
322 if (clazz == null) {
323 return false;
324 }
325
326 String className = clazz.getName();
327
328 if (!className.equals(_CLASS_NAME_SECURE_ACTION)) {
329 return false;
330 }
331
332 String classLocation = PACLClassUtil.getClassLocation(clazz);
333
334 return classLocation.contains("/osgi/felix/bin/felix.jar!");
335 }
336
337 protected boolean isResinJavaSessionSerializer() {
338 if (!ServerDetector.isResin()) {
339 return false;
340 }
341
342 for (int i = 7;; i++) {
343 Class<?> callerClass = Reflection.getCallerClass(i);
344
345 if (callerClass == null) {
346 return false;
347 }
348
349 String callerClassName = callerClass.getName();
350
351 if (!callerClassName.equals(_CLASS_NAME_JAVA_SESSION_SERIALIZER)) {
352 continue;
353 }
354
355 String actualClassLocation = PACLClassUtil.getClassLocation(
356 callerClass);
357 String expectedClassLocation = PathUtil.toUnixPath(
358 System.getProperty("resin.home") + "/lib/resin.jar!/");
359
360 if (actualClassLocation.contains(expectedClassLocation)) {
361 logReflect(callerClass, i);
362
363 return true;
364 }
365
366 return false;
367 }
368 }
369
370 protected boolean isResinReflectionAnnotatedType(Class<?> clazz) {
371 if (!ServerDetector.isResin()) {
372 return false;
373 }
374
375 String className = clazz.getName();
376
377 if (!className.equals(_CLASS_NAME_REFLECTION_ANNOTATED_TYPE)) {
378 return false;
379 }
380
381 String actualClassLocation = PACLClassUtil.getClassLocation(clazz);
382 String expectedClassLocation = PathUtil.toUnixPath(
383 System.getProperty("resin.home") + "/lib/resin.jar!/");
384
385 return actualClassLocation.contains(expectedClassLocation);
386 }
387
388 protected boolean isWebLogicAbstractApplicationContextDelegator(
389 Class<?> clazz) {
390
391 if (!ServerDetector.isWebLogic()) {
392 return false;
393 }
394
395 String className = clazz.getName();
396
397 if (!className.equals(
398 _CLASS_NAME_ABSTRACT_APPLICATION_CONTEXT_DELEGATOR)) {
399
400 return false;
401 }
402
403 String classLocation = PACLClassUtil.getClassLocation(clazz);
404
405 if (classLocation.contains(
406 "/modules/com.bea.core.weblogic.spring.instrument_") ||
407 classLocation.contains("/patch_jars/BUG")) {
408
409 return true;
410 }
411
412 return false;
413 }
414
415 protected boolean isWebLogicAbstractBeanDefinitionDelegator(
416 Class<?> clazz) {
417
418 if (!ServerDetector.isWebLogic()) {
419 return false;
420 }
421
422 String className = clazz.getName();
423
424 if (!className.equals(_CLASS_NAME_ABSTRACT_BEAN_DEFINITION_DELEGATOR)) {
425 return false;
426 }
427
428 String classLocation = PACLClassUtil.getClassLocation(clazz);
429
430 if (classLocation.contains(
431 "/modules/com.bea.core.weblogic.spring.instrument_") ||
432 classLocation.contains("/patch_jars/BUG")) {
433
434 return true;
435 }
436
437 return false;
438 }
439
440 protected void logReflect(Class<?> callerClass, int frame) {
441 if (_log.isInfoEnabled()) {
442 _log.info(
443 "Allowing frame " + frame + " with caller " + callerClass +
444 " to reflect");
445 }
446 }
447
448 private static final String _CLASS_NAME_ABSTRACT_BEAN_DEFINITION_DELEGATOR =
449 "weblogic.spring.monitoring.utils.AbstractBeanDefinitionDelegator";
450
451 private static final String
452 _CLASS_NAME_ABSTRACT_APPLICATION_CONTEXT_DELEGATOR =
453 "weblogic.spring.monitoring.utils." +
454 "AbstractApplicationContextDelegator";
455
456 private static final String _CLASS_NAME_JAVA_SESSION_SERIALIZER =
457 "com.caucho.server.session.JavaSessionSerializer";
458
459 private static final String _CLASS_NAME_REFLECTION_ANNOTATED_TYPE =
460 "com.caucho.config.reflect.ReflectionAnnotatedType";
461
462 private static final String _CLASS_NAME_SECURE_ACTION =
463 "org.apache.felix.framework.util.SecureAction";
464
465 private static Log _log = LogFactoryUtil.getLog(BaseReflectChecker.class);
466
467 }