001    /**
002     * Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
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.util.JavaDetector;
020    import com.liferay.portal.kernel.util.PathUtil;
021    import com.liferay.portal.kernel.util.ServerDetector;
022    import com.liferay.portal.kernel.util.StringPool;
023    import com.liferay.portal.kernel.util.StringUtil;
024    import com.liferay.portal.security.lang.PortalSecurityManagerThreadLocal;
025    import com.liferay.portal.security.pacl.PACLClassUtil;
026    import com.liferay.portal.util.ClassLoaderUtil;
027    
028    import java.security.AccessController;
029    import java.security.Permission;
030    
031    import java.util.ArrayList;
032    import java.util.List;
033    import java.util.Set;
034    import java.util.TreeSet;
035    import java.util.regex.Matcher;
036    import java.util.regex.Pattern;
037    
038    import org.apache.xerces.impl.dv.DatatypeException;
039    import org.apache.xerces.parsers.AbstractDOMParser;
040    
041    import org.springframework.beans.CachedIntrospectionResults;
042    import org.springframework.context.support.AbstractApplicationContext;
043    import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
044    import org.springframework.util.ClassUtils;
045    
046    import sun.reflect.Reflection;
047    
048    /**
049     * @author Raymond Augé
050     * @author Brian Wing Shun Chan
051     */
052    public class RuntimeChecker extends BaseReflectChecker {
053    
054            public void afterPropertiesSet() {
055                    initClassLoaderReferenceIds();
056                    initEnvironmentVariables();
057            }
058    
059            public void checkPermission(Permission permission) {
060                    String name = permission.getName();
061    
062                    if (name.startsWith(RUNTIME_PERMISSION_ACCESS_CLASS_IN_PACKAGE)) {
063                            int pos = name.indexOf(StringPool.PERIOD);
064    
065                            String pkg = name.substring(pos + 1);
066    
067                            if (!hasAccessClassInPackage(pkg)) {
068                                    throwSecurityException(
069                                            _log, "Attempted to access package " + pkg);
070                            }
071                    }
072                    else if (name.equals(RUNTIME_PERMISSION_ACCESS_DECLARED_MEMBERS)) {
073                            if (!hasReflect(permission)) {
074                                    throwSecurityException(
075                                            _log, "Attempted to access declared members");
076                            }
077                    }
078                    else if (name.equals(RUNTIME_PERMISSION_CREATE_CLASS_LOADER)) {
079                            if (PortalSecurityManagerThreadLocal.isCheckCreateClassLoader() &&
080                                    !isJSPCompiler(permission.getName(), permission.getActions()) &&
081                                    !hasCreateClassLoader()) {
082    
083                                    throwSecurityException(
084                                            _log, "Attempted to create a class loader");
085                            }
086                    }
087                    else if (name.equals(RUNTIME_PERMISSION_CREATE_SECURITY_MANAGER)) {
088                            if (!hasCreateSecurityManager()) {
089                                    throwSecurityException(
090                                            _log, "Attempted to create a security manager");
091                            }
092                    }
093                    else if (name.startsWith(RUNTIME_PERMISSION_GET_CLASSLOADER)) {
094                            if (PortalSecurityManagerThreadLocal.isCheckGetClassLoader() &&
095                                    !isJSPCompiler(permission.getName(), permission.getActions()) &&
096                                    !hasGetClassLoader(name)) {
097    
098                                    throwSecurityException(_log, "Attempted to get class loader");
099                            }
100                    }
101                    else if (name.startsWith(RUNTIME_PERMISSION_GET_PROTECTION_DOMAIN)) {
102                            if (!hasGetProtectionDomain()) {
103                                    throwSecurityException(
104                                            _log, "Attempted to get protection domain");
105                            }
106                    }
107                    else if (name.startsWith(RUNTIME_PERMISSION_GET_ENV)) {
108                            int pos = name.indexOf(StringPool.PERIOD);
109    
110                            String envName = name.substring(pos + 1);
111    
112                            if (!hasGetEnv(envName)) {
113                                    throwSecurityException(
114                                            _log, "Attempted to get environment name " + envName);
115                            }
116                    }
117                    else if (name.startsWith(RUNTIME_PERMISSION_LOAD_LIBRARY)) {
118                            if (!hasLoadLibrary()) {
119                                    throwSecurityException(_log, "Attempted to load library");
120                            }
121                    }
122                    else if (name.equals(RUNTIME_PERMISSION_READ_FILE_DESCRIPTOR)) {
123                            if (PortalSecurityManagerThreadLocal.isCheckReadFileDescriptor() &&
124                                    !hasReadFileDescriptor()) {
125    
126                                    throwSecurityException(
127                                            _log, "Attempted to read file descriptor");
128                            }
129                    }
130                    else if (name.equals(RUNTIME_PERMISSION_SET_CONTEXT_CLASS_LOADER)) {
131                    }
132                    else if (name.equals(RUNTIME_PERMISSION_SET_SECURITY_MANAGER)) {
133                            throwSecurityException(
134                                    _log, "Attempted to set another security manager");
135                    }
136                    else if (name.equals(RUNTIME_PERMISSION_WRITE_FILE_DESCRIPTOR)) {
137                            if (PortalSecurityManagerThreadLocal.isCheckWriteFileDescriptor() &&
138                                    !hasWriteFileDescriptor()) {
139    
140                                    throwSecurityException(
141                                            _log, "Attempted to write file descriptor");
142                            }
143                    }
144                    else {
145                            if (_log.isDebugEnabled()) {
146                                    Thread.dumpStack();
147                            }
148    
149                            throwSecurityException(
150                                    _log,
151                                    "Attempted to " + permission.getName() + " on " +
152                                            permission.getActions());
153                    }
154            }
155    
156            @Override
157            public AuthorizationProperty generateAuthorizationProperty(
158                    Object... arguments) {
159    
160                    if ((arguments == null) || (arguments.length != 1) ||
161                            !(arguments[0] instanceof Permission)) {
162    
163                            return null;
164                    }
165    
166                    Permission permission = (Permission)arguments[0];
167    
168                    String name = permission.getName();
169    
170                    String key = null;
171                    String value = null;
172    
173                    if (name.startsWith(RUNTIME_PERMISSION_GET_CLASSLOADER)) {
174                            key = "security-manager-class-loader-reference-ids";
175    
176                            if (name.equals(RUNTIME_PERMISSION_GET_CLASSLOADER)) {
177                                    value = "portal";
178                            }
179                            else {
180                                    value = name.substring(
181                                            RUNTIME_PERMISSION_GET_CLASSLOADER.length() + 1);
182                            }
183                    }
184                    else if (name.startsWith(RUNTIME_PERMISSION_GET_ENV)) {
185                            key = "security-manager-environment-variables";
186    
187                            value = name.substring(RUNTIME_PERMISSION_GET_ENV.length() + 1);
188    
189                            // Since we are using a regular expression, we cannot allow a lone *
190                            // as the rule
191    
192                            if (value.equals(StringPool.STAR)) {
193                                    value = StringPool.DOUBLE_BACK_SLASH + value;
194                            }
195                    }
196                    else {
197                            return null;
198                    }
199    
200                    AuthorizationProperty authorizationProperty =
201                            new AuthorizationProperty();
202    
203                    authorizationProperty.setKey(key);
204                    authorizationProperty.setValue(value);
205    
206                    return authorizationProperty;
207            }
208    
209            protected boolean hasAccessClassInPackage(String pkg) {
210    
211                    // TODO
212    
213                    if (pkg.startsWith("sun.reflect")) {
214                    }
215    
216                    return true;
217            }
218    
219            protected boolean hasCreateClassLoader() {
220                    if (JavaDetector.isIBM()) {
221                            Class<?> callerClass9 = Reflection.getCallerClass(9);
222    
223                            String callerClassName9 = callerClass9.getName();
224    
225                            if (callerClassName9.startsWith(_CLASS_NAME_CLASS_DEFINER) &&
226                                    CheckerUtil.isAccessControllerDoPrivileged(10)) {
227    
228                                    logCreateClassLoader(callerClass9, 9);
229    
230                                    return true;
231                            }
232    
233                            Class<?> callerClass10 = Reflection.getCallerClass(10);
234    
235                            String callerClassName10 = callerClass10.getName();
236    
237                            if (callerClassName10.startsWith(_CLASS_NAME_CLASS_DEFINER) &&
238                                    CheckerUtil.isAccessControllerDoPrivileged(11)) {
239    
240                                    logCreateClassLoader(callerClass10, 10);
241    
242                                    return true;
243                            }
244                    }
245                    else if (JavaDetector.isJDK7()) {
246                            Class<?> callerClass11 = Reflection.getCallerClass(11);
247    
248                            String callerClassName11 = callerClass11.getName();
249    
250                            if (callerClassName11.startsWith(_CLASS_NAME_CLASS_DEFINER) &&
251                                    CheckerUtil.isAccessControllerDoPrivileged(12)) {
252    
253                                    logCreateClassLoader(callerClass11, 11);
254    
255                                    return true;
256                            }
257                    }
258                    else {
259                            Class<?> callerClass10 = Reflection.getCallerClass(10);
260    
261                            String callerClassName10 = callerClass10.getName();
262    
263                            if (callerClassName10.startsWith(_CLASS_NAME_CLASS_DEFINER) &&
264                                    CheckerUtil.isAccessControllerDoPrivileged(11)) {
265    
266                                    logCreateClassLoader(callerClass10, 10);
267    
268                                    return true;
269                            }
270                    }
271    
272                    return false;
273            }
274    
275            protected boolean hasCreateSecurityManager() {
276                    Class<?> callerClass7 = Reflection.getCallerClass(7);
277    
278                    String callerClassName7 = callerClass7.getName();
279    
280                    if (callerClassName7.startsWith("javax.crypto") &&
281                            CheckerUtil.isAccessControllerDoPrivileged(10)) {
282    
283                            logCreateSecurityManager(callerClass7, 7);
284    
285                            return true;
286                    }
287    
288                    return false;
289            }
290    
291            protected boolean hasGetClassLoader(String name) {
292                    int pos = name.indexOf(StringPool.PERIOD);
293    
294                    if (pos != -1) {
295                            String referenceId = name.substring(pos + 1);
296    
297                            if (_classLoaderReferenceIds.contains(referenceId)) {
298                                    return true;
299                            }
300    
301                            if (referenceId.equals("portal")) {
302                                    Class<?> callerClass7 = Reflection.getCallerClass(7);
303    
304                                    if (isTrustedCallerClass(callerClass7)) {
305                                            return true;
306                                    }
307                            }
308    
309                            return false;
310                    }
311    
312                    Class<?> callerClass6 = Reflection.getCallerClass(6);
313                    Class<?> callerClass7 = Reflection.getCallerClass(7);
314    
315                    if (_log.isDebugEnabled()) {
316                            _log.debug(
317                                    callerClass7.getName() +
318                                            " is attempting to get the class loader via " +
319                                                    callerClass6.getName());
320                    }
321    
322                    if ((callerClass7 == CachedIntrospectionResults.class) ||
323                            (callerClass7 == ClassUtils.class) ||
324                            (callerClass7.getEnclosingClass() ==
325                                    LocalVariableTableParameterNameDiscoverer.class)) {
326    
327                            logGetClassLoader(callerClass7, 7);
328    
329                            return true;
330                    }
331    
332                    if (callerClass6 == Class.class) {
333                            if (isJBossMessages(callerClass7) ||
334                                    isJBossServiceControllerImpl(callerClass7) ||
335                                    isJOnASModuleImpl(callerClass7) ||
336                                    isTomcatJdbcLeakPrevention(callerClass7)) {
337    
338                                    logGetClassLoader(callerClass7, 7);
339    
340                                    return true;
341                            }
342    
343                            if (isWebSphereProtectionClassLoader(
344                                            callerClass7.getEnclosingClass()) &&
345                                    CheckerUtil.isAccessControllerDoPrivileged(8)) {
346    
347                                    logGetClassLoader(callerClass7, 7);
348    
349                                    return true;
350                            }
351                    }
352                    else if (callerClass6 == ClassLoader.class) {
353                            Class<?> callerClass8 = Reflection.getCallerClass(8);
354    
355                            if (isGlassfishAPIClassLoaderServiceImpl(
356                                            callerClass8.getEnclosingClass()) &&
357                                    CheckerUtil.isAccessControllerDoPrivileged(9)) {
358    
359                                    logGetClassLoader(callerClass8, 8);
360    
361                                    return true;
362                            }
363    
364                            if (isResinEnvironmentLocal(callerClass7)) {
365                                    logGetClassLoader(callerClass7, 7);
366    
367                                    return true;
368                            }
369    
370                            if (isWebLogicGenericClassLoader(
371                                            callerClass7.getEnclosingClass()) &&
372                                    CheckerUtil.isAccessControllerDoPrivileged(8)) {
373    
374                                    logGetClassLoader(callerClass7, 7);
375    
376                                    return true;
377                            }
378    
379                            if (isXercesSecuritySupport(callerClass7) &&
380                                    CheckerUtil.isAccessControllerDoPrivileged(8)) {
381    
382                                    logGetClassLoader(callerClass8, 8);
383    
384                                    return true;
385                            }
386    
387                            Thread currentThread = Thread.currentThread();
388    
389                            StackTraceElement[] stackTraceElements =
390                                    currentThread.getStackTrace();
391    
392                            StackTraceElement stackTraceElement = null;
393    
394                            if (JavaDetector.isIBM()) {
395                                    stackTraceElement = stackTraceElements[7];
396                            }
397                            else {
398                                    stackTraceElement = stackTraceElements[6];
399                            }
400    
401                            String methodName = stackTraceElement.getMethodName();
402    
403                            if (methodName.equals(_METHOD_NAME_GET_SYSTEM_CLASS_LOADER)) {
404                                    if (_log.isInfoEnabled()) {
405                                            _log.info(
406                                                    "Allowing " + callerClass7.getName() +
407                                                            " to get the system class loader");
408                                    }
409    
410                                    return true;
411                            }
412                    }
413                    else if (callerClass6 == Thread.class) {
414                            boolean allow = false;
415    
416                            ClassLoader contextClassLoader =
417                                    ClassLoaderUtil.getContextClassLoader();
418                            ClassLoader portalClassLoader = getPortalClassLoader();
419    
420                            if (contextClassLoader == portalClassLoader) {
421                                    if (ClassLoaderUtil.getClassLoader(callerClass7) !=
422                                                    getClassLoader()) {
423    
424                                            allow = true;
425                                    }
426                            }
427                            else {
428                                    allow = true;
429                            }
430    
431                            if (allow) {
432                                    if (_log.isInfoEnabled()) {
433                                            _log.info(
434                                                    "Allowing " + callerClass7.getName() +
435                                                            " to access the context class loader");
436                                    }
437    
438                                    return true;
439                            }
440                    }
441    
442                    return false;
443            }
444    
445            protected boolean hasGetEnv(String name) {
446                    for (Pattern environmentVariablePattern :
447                                    _environmentVariablePatterns) {
448    
449                            Matcher matcher = environmentVariablePattern.matcher(name);
450    
451                            if (matcher.matches()) {
452                                    return true;
453                            }
454                    }
455    
456                    Class<?> callerClass7 = Reflection.getCallerClass(7);
457    
458                    if (callerClass7 == AbstractApplicationContext.class) {
459                            logGetEnv(callerClass7, 7, name);
460    
461                            return true;
462                    }
463    
464                    if (ServerDetector.isWebSphere()) {
465                            if (name.equals("USER_INSTALL_ROOT")) {
466                                    return true;
467                            }
468                    }
469    
470                    return false;
471            }
472    
473            protected boolean hasGetProtectionDomain() {
474                    Class<?> callerClass8 = Reflection.getCallerClass(8);
475    
476                    if (((callerClass8 == AccessController.class) &&
477                                    CheckerUtil.isAccessControllerDoPrivileged(8)) ||
478                            (isDefaultMBeanServerInterceptor(
479                                    callerClass8.getEnclosingClass()) &&
480                             CheckerUtil.isAccessControllerDoPrivileged(9))) {
481    
482                            logGetProtectionDomain(callerClass8, 8);
483    
484                            return true;
485                    }
486    
487                    return false;
488            }
489    
490            protected boolean hasLoadLibrary() {
491                    Class<?> callerClass10 = Reflection.getCallerClass(10);
492    
493                    if ((callerClass10 == AccessController.class) &&
494                            CheckerUtil.isAccessControllerDoPrivileged(10)) {
495    
496                            return true;
497                    }
498    
499                    return false;
500            }
501    
502            protected boolean hasReadFileDescriptor() {
503                    if (JavaDetector.isJDK7()) {
504                            Class<?> callerClass9 = Reflection.getCallerClass(9);
505    
506                            String callerClassName9 = callerClass9.getName();
507    
508                            if (callerClassName9.startsWith(_CLASS_NAME_PROCESS_IMPL) &&
509                                    CheckerUtil.isAccessControllerDoPrivileged(10)) {
510    
511                                    logWriteFileDescriptor(callerClass9, 9);
512    
513                                    return true;
514                            }
515                    }
516                    else {
517                            Class<?> callerClass8 = Reflection.getCallerClass(8);
518    
519                            String callerClassName8 = callerClass8.getName();
520    
521                            if (callerClassName8.startsWith(_CLASS_NAME_PROCESS_IMPL) &&
522                                    CheckerUtil.isAccessControllerDoPrivileged(9)) {
523    
524                                    logWriteFileDescriptor(callerClass8, 8);
525    
526                                    return true;
527                            }
528                    }
529    
530                    return false;
531            }
532    
533            protected boolean hasWriteFileDescriptor() {
534                    if (JavaDetector.isJDK7()) {
535                            Class<?> callerClass9 = Reflection.getCallerClass(9);
536    
537                            String callerClassName9 = callerClass9.getName();
538    
539                            if (callerClassName9.startsWith(_CLASS_NAME_PROCESS_IMPL) &&
540                                    CheckerUtil.isAccessControllerDoPrivileged(10)) {
541    
542                                    logWriteFileDescriptor(callerClass9, 9);
543    
544                                    return true;
545                            }
546                    }
547                    else {
548                            Class<?> callerClass8 = Reflection.getCallerClass(8);
549    
550                            String callerClassName8 = callerClass8.getName();
551    
552                            if (callerClassName8.startsWith(_CLASS_NAME_PROCESS_IMPL) &&
553                                    CheckerUtil.isAccessControllerDoPrivileged(9)) {
554    
555                                    logWriteFileDescriptor(callerClass8, 8);
556    
557                                    return true;
558                            }
559                    }
560    
561                    return false;
562            }
563    
564            protected void initClassLoaderReferenceIds() {
565                    _classLoaderReferenceIds = getPropertySet(
566                            "security-manager-class-loader-reference-ids");
567    
568                    if (_log.isDebugEnabled()) {
569                            Set<String> referenceIds = new TreeSet<String>(
570                                    _classLoaderReferenceIds);
571    
572                            for (String referenceId : referenceIds) {
573                                    _log.debug(
574                                            "Allowing access to class loader for reference " +
575                                                    referenceId);
576                            }
577                    }
578            }
579    
580            protected void initEnvironmentVariables() {
581                    Set<String> environmentVariables = getPropertySet(
582                            "security-manager-environment-variables");
583    
584                    _environmentVariablePatterns = new ArrayList<Pattern>(
585                            environmentVariables.size());
586    
587                    for (String environmentVariable : environmentVariables) {
588                            Pattern environmentVariablePattern = Pattern.compile(
589                                    environmentVariable);
590    
591                            _environmentVariablePatterns.add(environmentVariablePattern);
592    
593                            if (_log.isDebugEnabled()) {
594                                    _log.debug(
595                                            "Allowing access to environment variables that match " +
596                                                    "the regular expression " + environmentVariable);
597                            }
598                    }
599            }
600    
601            protected boolean isDefaultMBeanServerInterceptor(Class<?> clazz) {
602                    String className = clazz.getName();
603    
604                    if (!className.equals(_CLASS_NAME_DEFAULT_MBEAN_SERVER_INTERCEPTOR)) {
605                            return false;
606                    }
607    
608                    String classLocation = PACLClassUtil.getClassLocation(clazz);
609    
610                    if (classLocation.length() > 0) {
611                            return false;
612                    }
613    
614                    return true;
615            }
616    
617            protected boolean isGlassfishAPIClassLoaderServiceImpl(Class<?> clazz) {
618                    if (!ServerDetector.isGlassfish()) {
619                            return false;
620                    }
621    
622                    if (clazz == null) {
623                            return false;
624                    }
625    
626                    clazz = clazz.getEnclosingClass();
627    
628                    if (clazz == null) {
629                            return false;
630                    }
631    
632                    String className = clazz.getName();
633    
634                    if (!className.equals(_CLASS_NAME_API_CLASS_LOADER_SERVICE_IMPL)) {
635                            return false;
636                    }
637    
638                    String classLocation = PACLClassUtil.getClassLocation(clazz);
639    
640                    return classLocation.startsWith("bundle://");
641            }
642    
643            protected boolean isJBossMessages(Class<?> clazz) {
644                    if (!ServerDetector.isJBoss()) {
645                            return false;
646                    }
647    
648                    String className = clazz.getName();
649    
650                    if (!className.equals(_CLASS_NAME_MESSAGES)) {
651                            return false;
652                    }
653    
654                    String classLocation = PACLClassUtil.getClassLocation(clazz);
655    
656                    return classLocation.contains(
657                            "/modules/org/jboss/logging/main/jboss-logging-");
658            }
659    
660            protected boolean isJBossServiceControllerImpl(Class<?> clazz) {
661                    if (!ServerDetector.isJBoss()) {
662                            return false;
663                    }
664    
665                    String className = clazz.getName();
666    
667                    if (!className.equals(_CLASS_NAME_SERVICE_CONTROLLER_IMPL)) {
668                            return false;
669                    }
670    
671                    String classLocation = PACLClassUtil.getClassLocation(clazz);
672    
673                    return classLocation.contains("/modules/org/jboss/msc/main/jboss-msc-");
674            }
675    
676            protected boolean isJOnASModuleImpl(Class<?> clazz) {
677                    if (!ServerDetector.isJOnAS()) {
678                            return false;
679                    }
680    
681                    String className = clazz.getName();
682    
683                    if (!className.equals(_CLASS_NAME_MODULE_IMPL)) {
684                            return false;
685                    }
686    
687                    String classLocation = PACLClassUtil.getClassLocation(clazz);
688    
689                    return classLocation.contains("/lib/bootstrap/felix-launcher.jar!/");
690            }
691    
692            protected boolean isResinEnvironmentLocal(Class<?> clazz) {
693                    if (!ServerDetector.isResin()) {
694                            return false;
695                    }
696    
697                    String className = clazz.getName();
698    
699                    if (!className.equals(_CLASS_NAME_ENVIRONMENT_LOCAL)) {
700                            return false;
701                    }
702    
703                    String actualClassLocation = PACLClassUtil.getClassLocation(clazz);
704                    String expectedClassLocation = PathUtil.toUnixPath(
705                            System.getProperty("resin.home") + "/lib/resin.jar!/");
706    
707                    return actualClassLocation.contains(expectedClassLocation);
708            }
709    
710            protected boolean isTomcatJdbcLeakPrevention(Class<?> clazz) {
711                    if (!ServerDetector.isTomcat()) {
712                            return false;
713                    }
714    
715                    String className = clazz.getName();
716    
717                    if (!className.equals(_CLASS_NAME_JDBC_LEAK_PREVENTION)) {
718                            return false;
719                    }
720    
721                    String actualClassLocation = PACLClassUtil.getClassLocation(clazz);
722    
723                    String expectedClassLocation = PathUtil.toUnixPath(
724                            System.getProperty("catalina.base") + "/lib/catalina.jar!/");
725    
726                    expectedClassLocation += StringUtil.replace(
727                            className, StringPool.PERIOD, StringPool.SLASH);
728                    expectedClassLocation += ".class";
729    
730                    if (_log.isDebugEnabled()) {
731                            _log.debug("Actual class location " + actualClassLocation);
732                            _log.debug("Expected class location " + expectedClassLocation);
733                    }
734    
735                    return actualClassLocation.endsWith(expectedClassLocation);
736            }
737    
738            protected boolean isWebLogicGenericClassLoader(Class<?> clazz) {
739                    if (!ServerDetector.isWebLogic()) {
740                            return false;
741                    }
742    
743                    if (clazz == null) {
744                            return false;
745                    }
746    
747                    String className = clazz.getName();
748    
749                    if (!className.equals(_CLASS_NAME_GENERIC_CLASS_LOADER)) {
750                            return false;
751                    }
752    
753                    String classLocation = PACLClassUtil.getClassLocation(clazz);
754    
755                    if (classLocation.contains(
756                                    "/modules/com.bea.core.utils.classloaders_") ||
757                            classLocation.contains("/patch_jars/BUG")) {
758    
759                            return true;
760                    }
761    
762                    return false;
763            }
764    
765            protected boolean isWebSphereProtectionClassLoader(Class<?> clazz) {
766                    if (!ServerDetector.isWebSphere()) {
767                            return false;
768                    }
769    
770                    if (clazz == null) {
771                            return false;
772                    }
773    
774                    String className = clazz.getName();
775    
776                    if (!className.equals(_CLASS_NAME_PROTECTION_CLASS_LOADER)) {
777                            return false;
778                    }
779    
780                    String classLocation = PACLClassUtil.getClassLocation(clazz);
781    
782                    return classLocation.startsWith("bundleresource://");
783            }
784    
785            protected boolean isXercesSecuritySupport(Class<?> clazz) {
786                    String className = clazz.getName();
787    
788                    if (className.contains(".SecuritySupport$") &&
789                            ((clazz.getPackage() == AbstractDOMParser.class.getPackage()) ||
790                             (clazz.getPackage() == DatatypeException.class.getPackage()))) {
791    
792                            return true;
793                    }
794    
795                    return false;
796            }
797    
798            protected void logCreateClassLoader(Class<?> callerClass, int frame) {
799                    if (_log.isInfoEnabled()) {
800                            _log.info(
801                                    "Allowing frame " + frame + " with caller " + callerClass +
802                                            " to create a class loader");
803                    }
804            }
805    
806            protected void logCreateSecurityManager(Class<?> callerClass, int frame) {
807                    if (_log.isInfoEnabled()) {
808                            _log.info(
809                                    "Allowing frame " + frame + " with caller " + callerClass +
810                                            "to create a security manager");
811                    }
812            }
813    
814            protected void logGetClassLoader(Class<?> callerClass, int frame) {
815                    if (_log.isInfoEnabled()) {
816                            _log.info(
817                                    "Allowing frame " + frame + " with caller " + callerClass +
818                                            " to get the class loader");
819                    }
820            }
821    
822            protected void logGetEnv(Class<?> callerClass, int frame, String name) {
823                    if (_log.isInfoEnabled()) {
824                            _log.info(
825                                    "Allowing frame " + frame + " with caller " + callerClass +
826                                            " to get environment " + name);
827                    }
828            }
829    
830            protected void logGetProtectionDomain(Class<?> callerClass, int frame) {
831                    if (_log.isInfoEnabled()) {
832                            _log.info(
833                                    "Allowing frame " + frame + " with caller " + callerClass +
834                                            " to get the protection domain");
835                    }
836            }
837    
838            protected void logReadFileDescriptor(Class<?> callerClass, int frame) {
839                    if (_log.isInfoEnabled()) {
840                            _log.info(
841                                    "Allowing frame " + frame + " with caller " + callerClass +
842                                            " to read a file descriptor");
843                    }
844            }
845    
846            protected void logWriteFileDescriptor(Class<?> callerClass, int frame) {
847                    if (_log.isInfoEnabled()) {
848                            _log.info(
849                                    "Allowing frame " + frame + " with caller " + callerClass +
850                                            " to write a file descriptor");
851                    }
852            }
853    
854            private static final String _CLASS_NAME_API_CLASS_LOADER_SERVICE_IMPL =
855                    "com.sun.enterprise.v3.server.APIClassLoaderServiceImpl";
856    
857            private static final String _CLASS_NAME_CLASS_DEFINER =
858                    "sun.reflect.ClassDefiner$";
859    
860            private static final String _CLASS_NAME_DEFAULT_MBEAN_SERVER_INTERCEPTOR =
861                    "com.sun.jmx.interceptor.DefaultMBeanServerInterceptor";
862    
863            private static final String _CLASS_NAME_ENVIRONMENT_LOCAL =
864                    "com.caucho.loader.EnvironmentLocal";
865    
866            private static final String _CLASS_NAME_GENERIC_CLASS_LOADER =
867                    "weblogic.utils.classloaders.GenericClassLoader";
868    
869            private static final String _CLASS_NAME_JDBC_LEAK_PREVENTION =
870                    "org.apache.catalina.loader.JdbcLeakPrevention";
871    
872            private static final String _CLASS_NAME_MESSAGES =
873                    "org.jboss.logging.Messages";
874    
875            private static final String _CLASS_NAME_MODULE_IMPL =
876                    "org.apache.felix.framework.ModuleImpl";
877    
878            private static final String _CLASS_NAME_PROCESS_IMPL =
879                    "java.lang.ProcessImpl$";
880    
881            private static final String _CLASS_NAME_PROTECTION_CLASS_LOADER =
882                    "com.ibm.ws.classloader.ProtectionClassLoader";
883    
884            private static final String _CLASS_NAME_SERVICE_CONTROLLER_IMPL =
885                    "org.jboss.msc.service.ServiceControllerImpl";
886    
887            private static final String _METHOD_NAME_GET_SYSTEM_CLASS_LOADER =
888                    "getSystemClassLoader";
889    
890            private static Log _log = LogFactoryUtil.getLog(RuntimeChecker.class);
891    
892            private Set<String> _classLoaderReferenceIds;
893            private List<Pattern> _environmentVariablePatterns;
894    
895    }