001    /**
002     * Copyright (c) 2000-2013 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;
016    
017    import com.liferay.portal.bean.BeanLocatorImpl;
018    import com.liferay.portal.dao.jdbc.DataSourceFactoryImpl;
019    import com.liferay.portal.dao.orm.hibernate.DynamicQueryFactoryImpl;
020    import com.liferay.portal.deploy.hot.HotDeployImpl;
021    import com.liferay.portal.freemarker.FreeMarkerTemplate;
022    import com.liferay.portal.freemarker.LiferayTemplateCache;
023    import com.liferay.portal.kernel.log.Log;
024    import com.liferay.portal.kernel.log.LogFactoryUtil;
025    import com.liferay.portal.kernel.portlet.PortletClassLoaderUtil;
026    import com.liferay.portal.kernel.security.pacl.PACLConstants;
027    import com.liferay.portal.kernel.security.pacl.permission.PortalFilePermission;
028    import com.liferay.portal.kernel.security.pacl.permission.PortalHookPermission;
029    import com.liferay.portal.kernel.security.pacl.permission.PortalMessageBusPermission;
030    import com.liferay.portal.kernel.security.pacl.permission.PortalRuntimePermission;
031    import com.liferay.portal.kernel.security.pacl.permission.PortalServicePermission;
032    import com.liferay.portal.kernel.security.pacl.permission.PortalSocketPermission;
033    import com.liferay.portal.kernel.servlet.taglib.FileAvailabilityUtil;
034    import com.liferay.portal.kernel.util.AggregateClassLoader;
035    import com.liferay.portal.kernel.util.AutoResetThreadLocal;
036    import com.liferay.portal.kernel.util.CentralizedThreadLocal;
037    import com.liferay.portal.kernel.util.JavaDetector;
038    import com.liferay.portal.kernel.util.PreloadClassLoader;
039    import com.liferay.portal.kernel.util.ProxyUtil;
040    import com.liferay.portal.kernel.util.ReflectionUtil;
041    import com.liferay.portal.kernel.util.Validator;
042    import com.liferay.portal.security.lang.DoPrivilegedBean;
043    import com.liferay.portal.security.lang.DoPrivilegedFactory;
044    import com.liferay.portal.security.lang.DoPrivilegedHandler;
045    import com.liferay.portal.security.lang.DoPrivilegedUtil;
046    import com.liferay.portal.security.lang.PortalSecurityManager;
047    import com.liferay.portal.security.pacl.dao.jdbc.PACLConnectionHandler;
048    import com.liferay.portal.security.pacl.dao.jdbc.PACLDataSource;
049    import com.liferay.portal.security.pacl.dao.jdbc.PACLStatementHandler;
050    import com.liferay.portal.security.pacl.jndi.PACLContext;
051    import com.liferay.portal.security.pacl.jndi.PACLInitialContextFactory;
052    import com.liferay.portal.security.pacl.jndi.PACLInitialContextFactoryBuilder;
053    import com.liferay.portal.security.pacl.servlet.PACLRequestDispatcherWrapper;
054    import com.liferay.portal.servlet.DirectRequestDispatcherFactoryImpl;
055    import com.liferay.portal.spring.aop.ServiceBeanAopProxy;
056    import com.liferay.portal.spring.context.PortletApplicationContext;
057    import com.liferay.portal.spring.util.FilterClassLoader;
058    import com.liferay.portal.template.AbstractProcessingTemplate;
059    import com.liferay.portal.template.BaseTemplateManager;
060    import com.liferay.portal.template.TemplateContextHelper;
061    import com.liferay.portal.template.TemplateControlContext;
062    import com.liferay.portal.util.ClassLoaderUtil;
063    import com.liferay.portal.util.PropsValues;
064    import com.liferay.portal.velocity.LiferayResourceManager;
065    import com.liferay.portal.velocity.VelocityTemplate;
066    import com.liferay.portal.xsl.XSLTemplate;
067    import com.liferay.portlet.PortletRequestImpl;
068    import com.liferay.portlet.PortletResponseImpl;
069    import com.liferay.portlet.PortletURLImpl;
070    
071    import java.lang.reflect.Field;
072    import java.lang.reflect.InvocationHandler;
073    import java.lang.reflect.Member;
074    import java.lang.reflect.Method;
075    import java.lang.reflect.ReflectPermission;
076    
077    import java.net.SocketPermission;
078    
079    import java.security.AccessControlContext;
080    import java.security.AccessController;
081    import java.security.Permission;
082    import java.security.Policy;
083    import java.security.PrivilegedAction;
084    import java.security.PrivilegedExceptionAction;
085    import java.security.ProtectionDomain;
086    
087    import java.util.HashMap;
088    import java.util.Map;
089    import java.util.Properties;
090    
091    import javax.ccpp.Profile;
092    
093    import javax.naming.spi.InitialContextFactoryBuilder;
094    import javax.naming.spi.NamingManager;
095    
096    import javax.servlet.RequestDispatcher;
097    import javax.servlet.ServletContext;
098    
099    import javax.sql.DataSource;
100    
101    import org.springframework.aop.framework.AdvisedSupport;
102    
103    import sun.reflect.Reflection;
104    
105    import sun.security.util.SecurityConstants;
106    
107    /**
108     * This is the portal's implementation of a security manager. The goal is to
109     * protect portal resources from plugins and prevent security issues by forcing
110     * plugin developers to openly declare their requirements. Where a
111     * SecurityManager exists, we set that as the parent and delegate to it as a
112     * fallback. This class will not delegate checks to super when there is no
113     * parent so as to avoid forcing the need for a default policy.
114     *
115     * @author Brian Wing Shun Chan
116     * @author Raymond Augé
117     * @author Zsolt Berentey
118     */
119    public class PortalSecurityManagerImpl extends SecurityManager
120            implements PortalSecurityManager {
121    
122            public PortalSecurityManagerImpl() {
123                    SecurityManager securityManager = System.getSecurityManager();
124    
125                    initClasses();
126    
127                    try {
128                            Policy policy = null;
129    
130                            if (securityManager != null) {
131                                    policy = Policy.getPolicy();
132                            }
133    
134                            _policy = new PortalPolicy(policy);
135    
136                            Policy.setPolicy(_policy);
137    
138                            _policy.refresh();
139                    }
140                    catch (Exception e) {
141                            if (_log.isInfoEnabled()) {
142                                    _log.info(
143                                            "Unable to override the original Java security policy " +
144                                                    "because sufficient privileges are not granted to " +
145                                                            "Liferay. PACL is not enabled.");
146                            }
147    
148                            if (_log.isWarnEnabled()) {
149                                    _log.warn(e, e);
150                            }
151    
152                            return;
153                    }
154    
155                    try {
156                            initInitialContextFactoryBuilder();
157                    }
158                    catch (Exception e) {
159                            if (_log.isInfoEnabled()) {
160                                    _log.info(
161                                            "Unable to override the initial context factory builder " +
162                                                    "because one already exists. JNDI security is not " +
163                                                            "enabled.");
164                            }
165    
166                            if (_log.isWarnEnabled()) {
167                                    _log.warn(e, e);
168                            }
169                    }
170    
171                    try {
172                            initPACLImpls();
173                    }
174                    catch (Exception e) {
175                            if (_log.isInfoEnabled()) {
176                                    _log.info(
177                                            "Unable to initialize portal runtime permissions. Some " +
178                                                    "portal runtime security is not enabled.");
179                            }
180    
181                            if (_log.isWarnEnabled()) {
182                                    _log.warn(e, e);
183                            }
184                    }
185            }
186    
187            @Override
188            public void checkMemberAccess(Class<?> clazz, int accessibility) {
189                    if (clazz == null) {
190                            throw new NullPointerException("Class cannot be null");
191                    }
192    
193                    ClassLoader clazzClassLoader = ClassLoaderUtil.getClassLoader(clazz);
194    
195                    if (accessibility == Member.PUBLIC) {
196                            _checkMemberAccessClassLoader.set(clazzClassLoader);
197    
198                            return;
199                    }
200    
201                    Class<?> stack[] = getClassContext();
202    
203                    // Stack depth of 4 should be the caller of one of the methods in
204                    // java.lang.Class that invoked the checkMember access. The stack should
205                    // look like:
206    
207                    // [3] someCaller
208                    // [2] java.lang.Class.someReflectionAPI
209                    // [1] java.lang.Class.checkMemberAccess
210                    // [0] SecurityManager.checkMemberAccess
211    
212                    if ((stack.length < 4) ||
213                            (ClassLoaderUtil.getClassLoader(stack[3]) != clazzClassLoader)) {
214    
215                            _checkMemberAccessClassLoader.set(null);
216    
217                            checkPermission(SecurityConstants.CHECK_MEMBER_ACCESS_PERMISSION);
218                    }
219                    else {
220                            _checkMemberAccessClassLoader.set(clazzClassLoader);
221                    }
222            }
223    
224            @Override
225            public void checkPermission(Permission permission) {
226                    boolean clearCheckMemberAccessClassLoader = true;
227    
228                    try {
229                            String name = permission.getName();
230    
231                            if ((permission instanceof ReflectPermission) &&
232                                    name.equals("suppressAccessChecks") &&
233                                    (_checkMemberAccessClassLoader.get() != null)) {
234    
235                                    // The "suppressAccessChecks" permission is particularly
236                                    // difficult to handle because the Java API does not have a
237                                    // mechanism to get the class on which the accessibility is
238                                    // being suppressed. This makes it difficult to differentiate
239                                    // between code changing its own accessibility (allowed) from
240                                    // accessibility changes on foreign code (not allowed). However,
241                                    // there is a common programming pattern we can take advantage
242                                    // of to short circuit the problem.
243    
244                                    // T t = clazz.getDeclared*(..);
245    
246                                    // t.setAccessible(true);
247    
248                                    // Call getDeclared* and immediately change the accessibility of
249                                    // it. The getDeclared* results in a call to
250                                    // SecurityManager#checkMemberAccess(Class, int). In the case
251                                    // where the target class and the caller class are from the same
252                                    // class loader, the checking is short circuited with a
253                                    // successful result. If this short circuit happens in our
254                                    // implementation, we will store the class loader of the target
255                                    // class, and on the very next permission check, if the check is
256                                    // for "suppressAccessChecks" and the classLoader of the caller
257                                    // is the same as the stored class loader from the previous
258                                    // check, we will also allow the check to succeed. In all cases,
259                                    // the thread local is purged to avoid later erroneous
260                                    // successes.
261    
262                                    Class<?> stack[] = getClassContext();
263    
264                                    // [2] someCaller
265                                    // [1] java.lang.reflect.AccessibleObject
266                                    // [0] SecurityManager.checkMemberAccess
267    
268                                    if (_checkMemberAccessClassLoader.get() ==
269                                                    ClassLoaderUtil.getClassLoader(stack[2])) {
270    
271                                            // The clearCheckMemberAccessClassLoader variable is set to
272                                            // false to support the calls to getDeclared*s that return
273                                            // an array.
274    
275                                            // T[] t = clazz.getDeclared*s(..);
276    
277                                            // We will hang onto the class loader as long as subsequent
278                                            // checks are for "suppressAccessChecks" and the class
279                                            // loader still matches.
280    
281                                            clearCheckMemberAccessClassLoader = false;
282    
283                                            return;
284                                    }
285                            }
286    
287                            AccessController.checkPermission(permission);
288                    }
289                    finally {
290                            if (clearCheckMemberAccessClassLoader) {
291                                    _checkMemberAccessClassLoader.set(null);
292                            }
293                    }
294            }
295    
296            public Policy getPolicy() {
297                    return _policy;
298            }
299    
300            protected void initClass(Class<?> clazz) {
301                    _log.debug(
302                            "Loading " + clazz.getName() + " and " +
303                                    clazz.getDeclaredClasses().length + " inner classes");
304            }
305    
306            protected void initClasses() {
307    
308                    // Load dependent classes to prevent ClassCircularityError
309    
310                    // This class' own inner classes
311    
312                    initClass(getClass());
313    
314                    // Other classes
315    
316                    initClass(AbstractProcessingTemplate.class);
317                    initClass(ActivePACLPolicy.class);
318                    initClass(BaseTemplateManager.class);
319                    initClass(CentralizedThreadLocal.class);
320                    initClass(DoPrivilegedBean.class);
321                    initClass(DoPrivilegedFactory.class);
322                    initClass(DoPrivilegedHandler.class);
323                    initClass(DynamicQueryFactoryImpl.class);
324                    initClass(FileAvailabilityUtil.class);
325                    initClass(FreeMarkerTemplate.class);
326                    initClass(GeneratingPACLPolicy.class);
327                    initClass(InactivePACLPolicy.class);
328                    initClass(LiferayResourceManager.class);
329                    initClass(LiferayTemplateCache.class);
330                    initClass(PACLConnectionHandler.class);
331                    initClass(PACLContext.class);
332                    initClass(PACLDataSource.class);
333                    initClass(PACLInvocationHandler.class);
334                    initClass(PACLInitialContextFactory.class);
335                    initClass(PACLInitialContextFactoryBuilder.class);
336                    initClass(PACLPolicyManager.class);
337                    initClass(PACLRequestDispatcherWrapper.class);
338                    initClass(PACLStatementHandler.class);
339                    initClass(PACLUtil.class);
340                    initClass(PortalPermissionCollection.class);
341                    initClass(PortalPolicy.class);
342                    initClass(PortletRequestImpl.class);
343                    initClass(PortletResponseImpl.class);
344                    initClass(PortletURLImpl.class);
345                    initClass(Profile.class);
346                    initClass(TemplateContextHelper.class);
347                    initClass(VelocityTemplate.class);
348                    initClass(XSLTemplate.class);
349            }
350    
351            protected void initInitialContextFactoryBuilder() throws Exception {
352                    if (!NamingManager.hasInitialContextFactoryBuilder()) {
353                            PACLInitialContextFactoryBuilder paclInitialContextFactoryBuilder =
354                                    new PACLInitialContextFactoryBuilder();
355    
356                            if (_log.isInfoEnabled()) {
357                                    _log.info("Overriding the initial context factory builder");
358                            }
359    
360                            NamingManager.setInitialContextFactoryBuilder(
361                                    paclInitialContextFactoryBuilder);
362                    }
363    
364                    Class<?> clazz = NamingManager.class;
365    
366                    String fieldName = "initctx_factory_builder";
367    
368                    if (JavaDetector.isIBM()) {
369                            fieldName = "icfb";
370                    }
371    
372                    Field field = clazz.getDeclaredField(fieldName);
373    
374                    field.setAccessible(true);
375    
376                    InitialContextFactoryBuilder initialContextFactoryBuilder =
377                            (InitialContextFactoryBuilder)field.get(null);
378    
379                    if (initialContextFactoryBuilder
380                                    instanceof PACLInitialContextFactoryBuilder) {
381    
382                            return;
383                    }
384    
385                    PACLInitialContextFactoryBuilder paclInitialContextFactoryBuilder =
386                            new PACLInitialContextFactoryBuilder();
387    
388                    paclInitialContextFactoryBuilder.setInitialContextFactoryBuilder(
389                            initialContextFactoryBuilder);
390    
391                    field.set(null, paclInitialContextFactoryBuilder);
392    
393                    if (_log.isInfoEnabled()) {
394                            _log.info(
395                                    "Overriding the initial context factory builder using " +
396                                            "reflection");
397                    }
398            }
399    
400            protected void initPACLImpl(Class<?> clazz, Object pacl) throws Exception {
401                    Field field = clazz.getDeclaredField("_pacl");
402    
403                    synchronized (field) {
404                            field.setAccessible(true);
405    
406                            field.set(null, pacl);
407                    }
408            }
409    
410            protected void initPACLImpls() throws Exception {
411                    initPACLImpl(BeanLocatorImpl.class, new DoBeanLocatorImplPACL());
412                    initPACLImpl(
413                            DataSourceFactoryImpl.class, new DoDataSourceFactoryImplPACL());
414                    initPACLImpl(
415                            DirectRequestDispatcherFactoryImpl.class,
416                            new DoDirectRequestDispatcherFactoryImplPACL());
417                    initPACLImpl(DoPrivilegedUtil.class, new DoDoPrivilegedPACL());
418                    initPACLImpl(HotDeployImpl.class, new DoHotDeployImplPACL());
419                    initPACLImpl(
420                            PortalFilePermission.class, new DoPortalFilePermissionPACL());
421                    initPACLImpl(
422                            PortalHookPermission.class, new DoPortalHookPermissionPACL());
423                    initPACLImpl(
424                            PortalMessageBusPermission.class,
425                            new DoPortalMessageBusPermissionPACL());
426                    initPACLImpl(
427                            PortalRuntimePermission.class, new DoPortalRuntimePermissionPACL());
428                    initPACLImpl(
429                            PortalServicePermission.class, new DoPortalServicePermissionPACL());
430                    initPACLImpl(
431                            PortalSocketPermission.class, new DoPortalSocketPermissionPACL());
432                    initPACLImpl(
433                            PortletApplicationContext.class,
434                            new DoPortletApplicationContextPACL());
435                    initPACLImpl(
436                            ServiceBeanAopProxy.class, new DoServiceBeanAopProxyPACL());
437                    initPACLImpl(
438                            TemplateContextHelper.class, new DoTemplateContextHelperPACL());
439            }
440    
441            private static Log _log = LogFactoryUtil.getLog(
442                    PortalSecurityManagerImpl.class.getName());
443    
444            private static ThreadLocal<ClassLoader> _checkMemberAccessClassLoader =
445                    new AutoResetThreadLocal<ClassLoader>(
446                            PortalSecurityManagerImpl.class +
447                                    "._checkMembersAccessClassLoader");
448    
449            private Policy _policy;
450    
451            private static class DoBeanLocatorImplPACL implements BeanLocatorImpl.PACL {
452    
453                    public Object getBean(final Object bean, ClassLoader classLoader) {
454                            if (classLoader == ClassLoaderUtil.getPortalClassLoader()) {
455                                    Class<?> callerClass = Reflection.getCallerClass(5);
456    
457                                    ClassLoader callerClassLoader = ClassLoaderUtil.getClassLoader(
458                                            callerClass);
459    
460                                    if (callerClassLoader == classLoader) {
461                                            return bean;
462                                    }
463                            }
464    
465                            InvocationHandler invocationHandler = new InvocationHandler() {
466    
467                                    public Object invoke(
468                                                    Object proxy, Method method, Object[] arguments)
469                                            throws Throwable {
470    
471                                            return method.invoke(bean, arguments);
472                                    }
473    
474                            };
475    
476                            invocationHandler = new PACLInvocationHandler(invocationHandler);
477    
478                            return ProxyUtil.newProxyInstance(
479                                    classLoader, ReflectionUtil.getInterfaces(bean, classLoader),
480                                    invocationHandler);
481                    }
482    
483            }
484    
485            private static class DoDataSourceFactoryImplPACL
486                    implements DataSourceFactoryImpl.PACL {
487    
488                    public DataSource getDataSource(DataSource dataSource) {
489                            return new PACLDataSource(dataSource);
490                    }
491    
492            }
493    
494            private static class DoDirectRequestDispatcherFactoryImplPACL
495                    implements DirectRequestDispatcherFactoryImpl.PACL {
496    
497                    public RequestDispatcher getRequestDispatcher(
498                            ServletContext servletContext,
499                            RequestDispatcher requestDispatcher) {
500    
501                            if (PACLPolicyManager.isActive()) {
502                                    requestDispatcher = new PACLRequestDispatcherWrapper(
503                                            servletContext, requestDispatcher);
504                            }
505    
506                            return requestDispatcher;
507                    }
508    
509            }
510    
511            private static class DoDoPrivilegedPACL implements DoPrivilegedUtil.PACL {
512    
513                    public <T> T wrap(PrivilegedAction<T> privilegedAction) {
514                            if (!PACLPolicyManager.isActive()) {
515                                    return privilegedAction.run();
516                            }
517    
518                            return DoPrivilegedFactory.wrap(
519                                    AccessController.doPrivileged(privilegedAction));
520                    }
521    
522                    public <T> T wrap(
523                                    PrivilegedExceptionAction<T> privilegedExceptionAction)
524                            throws Exception {
525    
526                            if (!PACLPolicyManager.isActive()) {
527                                    return privilegedExceptionAction.run();
528                            }
529    
530                            return DoPrivilegedFactory.wrap(
531                                    AccessController.doPrivileged(privilegedExceptionAction));
532                    }
533    
534                    public <T> T wrap(T t) {
535                            return DoPrivilegedFactory.wrap(t);
536                    }
537    
538                    public <T> T wrap(T t, boolean checkActive) {
539                            if (!PACLPolicyManager.isActive()) {
540                                    return t;
541                            }
542    
543                            return DoPrivilegedFactory.wrap(t);
544                    }
545    
546            }
547    
548            private static class DoHotDeployImplPACL implements HotDeployImpl.PACL {
549    
550                    public void initPolicy(
551                            String servletContextName, ClassLoader classLoader,
552                            Properties properties) {
553    
554                            PACLPolicy paclPolicy = PACLPolicyManager.buildPACLPolicy(
555                                    servletContextName, classLoader, properties);
556    
557                            PACLPolicyManager.register(classLoader, paclPolicy);
558                    }
559    
560                    public void unregister(ClassLoader classLoader) {
561                            PACLPolicyManager.unregister(classLoader);
562                    }
563    
564            }
565    
566            private static class DoPortalFilePermissionPACL
567                    implements PortalFilePermission.PACL {
568    
569                    public void checkCopy(String source, String destination) {
570                            SecurityManager securityManager = System.getSecurityManager();
571    
572                            if (securityManager == null) {
573                                    return;
574                            }
575    
576                            if (Validator.isNotNull(source)) {
577                                    securityManager.checkRead(source);
578                            }
579    
580                            if (Validator.isNull(destination)) {
581                                    return;
582                            }
583    
584                            securityManager.checkWrite(destination);
585                    }
586    
587                    public void checkDelete(String path) {
588                            SecurityManager securityManager = System.getSecurityManager();
589    
590                            if (securityManager == null) {
591                                    return;
592                            }
593    
594                            if (Validator.isNull(path)) {
595                                    return;
596                            }
597    
598                            securityManager.checkDelete(path);
599                    }
600    
601                    public void checkMove(String source, String destination) {
602                            SecurityManager securityManager = System.getSecurityManager();
603    
604                            if (securityManager == null) {
605                                    return;
606                            }
607    
608                            if (Validator.isNotNull(source)) {
609                                    securityManager.checkRead(source);
610                                    securityManager.checkDelete(source);
611                            }
612    
613                            if (Validator.isNull(destination)) {
614                                    return;
615                            }
616    
617                            securityManager.checkWrite(destination);
618                            securityManager.checkDelete(destination);
619                    }
620    
621                    public void checkRead(String path) {
622                            SecurityManager securityManager = System.getSecurityManager();
623    
624                            if (securityManager == null) {
625                                    return;
626                            }
627    
628                            if (Validator.isNull(path)) {
629                                    return;
630                            }
631    
632                            securityManager.checkRead(path);
633                    }
634    
635                    public void checkWrite(String path) {
636                            SecurityManager securityManager = System.getSecurityManager();
637    
638                            if (securityManager == null) {
639                                    return;
640                            }
641    
642                            if (Validator.isNull(path)) {
643                                    return;
644                            }
645    
646                            securityManager.checkWrite(path);
647                    }
648    
649            }
650    
651            private static class DoPortalHookPermissionPACL
652                    implements PortalHookPermission.PACL {
653    
654                    public void checkPermission(
655                            String name, ClassLoader portletClassLoader, Object subject) {
656    
657                            PACLPolicy paclPolicy = PACLPolicyManager.getPACLPolicy(
658                                    portletClassLoader);
659    
660                            if (paclPolicy == null) {
661                                    return;
662                            }
663    
664                            Permission permission = new PortalHookPermission(
665                                    name, portletClassLoader, subject);
666    
667                            if (!paclPolicy.implies(permission)) {
668                                    throw new SecurityException(permission.toString());
669                            }
670                    }
671    
672            }
673    
674            private static class DoPortalMessageBusPermissionPACL
675                    implements PortalMessageBusPermission.PACL {
676    
677                    public void checkListen(String destinationName) {
678                            SecurityManager securityManager = System.getSecurityManager();
679    
680                            if (securityManager == null) {
681                                    return;
682                            }
683    
684                            Permission permission = new PortalMessageBusPermission(
685                                    PACLConstants.PORTAL_MESSAGE_BUS_PERMISSION_LISTEN,
686                                    destinationName);
687    
688                            securityManager.checkPermission(permission);
689                    }
690    
691                    public void checkSend(String destinationName) {
692                            SecurityManager securityManager = System.getSecurityManager();
693    
694                            if (securityManager == null) {
695                                    return;
696                            }
697    
698                            Permission permission = new PortalMessageBusPermission(
699                                    PACLConstants.PORTAL_MESSAGE_BUS_PERMISSION_SEND,
700                                    destinationName);
701    
702                            securityManager.checkPermission(permission);
703                    }
704    
705            }
706    
707            private static class DoPortalRuntimePermissionPACL
708                    implements PortalRuntimePermission.PACL {
709    
710                    public void checkDynamicQuery(Class<?> implClass) {
711                            SecurityManager securityManager = System.getSecurityManager();
712    
713                            if (securityManager == null) {
714                                    return;
715                            }
716    
717                            ClassLoader classLoader = ClassLoaderUtil.getClassLoader(implClass);
718    
719                            PACLPolicy paclPolicy = PACLPolicyManager.getPACLPolicy(
720                                    classLoader);
721    
722                            if (paclPolicy == PACLUtil.getPACLPolicy()) {
723                                    return;
724                            }
725    
726                            String classLoaderReferenceId = "portal";
727    
728                            if (paclPolicy != null) {
729                                    classLoaderReferenceId = paclPolicy.getServletContextName();
730                            }
731    
732                            Permission permission = new PortalRuntimePermission(
733                                    PACLConstants.PORTAL_RUNTIME_PERMISSION_GET_CLASSLOADER, null,
734                                    classLoaderReferenceId);
735    
736                            securityManager.checkPermission(permission);
737                    }
738    
739                    public void checkExpandoBridge(String className) {
740                            SecurityManager securityManager = System.getSecurityManager();
741    
742                            if (securityManager == null) {
743                                    return;
744                            }
745    
746                            Permission permission = new PortalRuntimePermission(
747                                    PACLConstants.PORTAL_RUNTIME_PERMISSION_EXPANDO_BRIDGE, null,
748                                    className);
749    
750                            securityManager.checkPermission(permission);
751                    }
752    
753                    public void checkGetBeanProperty(
754                            String servletContextName, Class<?> clazz, String property) {
755    
756                            SecurityManager securityManager = System.getSecurityManager();
757    
758                            if (securityManager == null) {
759                                    return;
760                            }
761    
762                            Class<?> callerClass = Reflection.getCallerClass(5);
763    
764                            if (clazz == callerClass) {
765    
766                                    // The bean is calling its own getBean method
767    
768                                    return;
769                            }
770    
771                            clazz = PACLUtil.getClass(clazz);
772    
773                            Permission permission = new PortalRuntimePermission(
774                                    PACLConstants.PORTAL_RUNTIME_PERMISSION_GET_BEAN_PROPERTY,
775                                    servletContextName, clazz.getName(), property);
776    
777                            securityManager.checkPermission(permission);
778                    }
779    
780                    public void checkGetClassLoader(String classLoaderReferenceId) {
781                            SecurityManager securityManager = System.getSecurityManager();
782    
783                            if (securityManager == null) {
784                                    return;
785                            }
786    
787                            if (Validator.isNull(classLoaderReferenceId)) {
788                                    classLoaderReferenceId = "portal";
789                            }
790    
791                            Permission permission = new PortalRuntimePermission(
792                                    PACLConstants.PORTAL_RUNTIME_PERMISSION_GET_CLASSLOADER, null,
793                                    classLoaderReferenceId);
794    
795                            securityManager.checkPermission(permission);
796                    }
797    
798                    public void checkPortletBagPool(String portletId) {
799                            SecurityManager securityManager = System.getSecurityManager();
800    
801                            if (securityManager == null) {
802                                    return;
803                            }
804    
805                            Permission permission = new PortalRuntimePermission(
806                                    PACLConstants.PORTAL_RUNTIME_PERMISSION_PORTLET_BAG_POOL, null,
807                                    portletId);
808    
809                            securityManager.checkPermission(permission);
810                    }
811    
812                    public void checkSearchEngine(String searchEngineId) {
813                            SecurityManager securityManager = System.getSecurityManager();
814    
815                            if (securityManager == null) {
816                                    return;
817                            }
818    
819                            Permission permission = new PortalRuntimePermission(
820                                    PACLConstants.PORTAL_RUNTIME_PERMISSION_SEARCH_ENGINE, null,
821                                    searchEngineId);
822    
823                            securityManager.checkPermission(permission);
824                    }
825    
826                    public void checkSetBeanProperty(
827                            String servletContextName, Class<?> clazz, String property) {
828    
829                            SecurityManager securityManager = System.getSecurityManager();
830    
831                            if (securityManager == null) {
832                                    return;
833                            }
834    
835                            clazz = PACLUtil.getClass(clazz);
836    
837                            Permission permission = new PortalRuntimePermission(
838                                    PACLConstants.PORTAL_RUNTIME_PERMISSION_SET_BEAN_PROPERTY,
839                                    servletContextName, clazz.getName(), property);
840    
841                            securityManager.checkPermission(permission);
842                    }
843    
844                    public void checkThreadPoolExecutor(String name) {
845                            SecurityManager securityManager = System.getSecurityManager();
846    
847                            if (securityManager == null) {
848                                    return;
849                            }
850    
851                            Permission permission = new PortalRuntimePermission(
852                                    PACLConstants.PORTAL_RUNTIME_PERMISSION_THREAD_POOL_EXECUTOR,
853                                    null, name);
854    
855                            securityManager.checkPermission(permission);
856                    }
857    
858            }
859    
860            private static class DoPortalServicePermissionPACL
861                    implements PortalServicePermission.PACL {
862    
863                    public void checkService(
864                            Object object, Method method, Object[] arguments) {
865    
866                            SecurityManager securityManager = System.getSecurityManager();
867    
868                            if (securityManager == null) {
869                                    return;
870                            }
871    
872                            String methodName = method.getName();
873    
874                            if (methodName.equals("invokeMethod")) {
875                                    methodName = (String)arguments[0];
876                            }
877    
878                            Class<?> clazz = PACLUtil.getClass(object);
879    
880                            String className = PACLUtil.getServiceInterfaceName(
881                                    clazz.getName());
882    
883                            ClassLoader classLoader = ClassLoaderUtil.getClassLoader(clazz);
884    
885                            PACLPolicy paclPolicy = PACLPolicyManager.getPACLPolicy(
886                                    classLoader);
887    
888                            if (paclPolicy == PACLUtil.getPACLPolicy()) {
889                                    return;
890                            }
891    
892                            String servletContextName = "portal";
893    
894                            if (paclPolicy != null) {
895                                    servletContextName = paclPolicy.getServletContextName();
896                            }
897    
898                            PortalServicePermission portalServicePermission =
899                                    new PortalServicePermission(
900                                            PACLConstants.PORTAL_SERVICE_PERMISSION_SERVICE,
901                                            servletContextName, className, methodName);
902    
903                            securityManager.checkPermission(portalServicePermission);
904                    }
905    
906            }
907    
908            private static class DoPortalSocketPermissionPACL
909                    implements PortalSocketPermission.PACL {
910    
911                    public void checkPermission(String host, String action) {
912                            SecurityManager securityManager = System.getSecurityManager();
913    
914                            if (securityManager == null) {
915                                    return;
916                            }
917    
918                            Permission permission = new SocketPermission(host, action);
919    
920                            securityManager.checkPermission(permission);
921                    }
922    
923            }
924    
925            private static class DoPortletApplicationContextPACL
926                    implements PortletApplicationContext.PACL {
927    
928                    public ClassLoader getBeanClassLoader() {
929                            if (PACLPolicyManager.isActive()) {
930                                    return DoPrivilegedFactory.wrap(
931                                            new PreloadClassLoader(
932                                                    PortletClassLoaderUtil.getClassLoader(), _classes));
933                            }
934    
935                            ClassLoader beanClassLoader =
936                                    AggregateClassLoader.getAggregateClassLoader(
937                                            new ClassLoader[] {
938                                                    PortletClassLoaderUtil.getClassLoader(),
939                                                    ClassLoaderUtil.getPortalClassLoader()
940                                            });
941    
942                            return new FilterClassLoader(beanClassLoader);
943                    }
944    
945                    private static Map<String, Class<?>> _classes =
946                            new HashMap<String, Class<?>>();
947    
948                    static {
949                            for (String className :
950                                            PropsValues.
951                                                    PORTAL_SECURITY_MANAGER_PRELOAD_CLASSLOADER_CLASSES) {
952    
953                                    Class<?> clazz = null;
954    
955                                    try {
956                                            clazz = Class.forName(className);
957                                    }
958                                    catch (ClassNotFoundException cnfe) {
959                                            _log.error(cnfe, cnfe);
960                                    }
961    
962                                    _classes.put(clazz.getName(), clazz);
963                            }
964                    }
965    
966            }
967    
968            private static class DoServiceBeanAopProxyPACL
969                    implements ServiceBeanAopProxy.PACL {
970    
971                    public InvocationHandler getInvocationHandler(
972                            InvocationHandler invocationHandler,
973                            AdvisedSupport advisedSupport) {
974    
975                            return new PACLInvocationHandler(invocationHandler, advisedSupport);
976                    }
977    
978            }
979    
980            private static class DoTemplateContextHelperPACL
981                    implements TemplateContextHelper.PACL {
982    
983                    public TemplateControlContext getTemplateControlContext() {
984                            PACLPolicy paclPolicy = PACLUtil.getPACLPolicy();
985    
986                            ClassLoader contextClassLoader =
987                                    ClassLoaderUtil.getContextClassLoader();
988    
989                            if (paclPolicy == null) {
990                                    paclPolicy = PACLPolicyManager.getPACLPolicy(
991                                            contextClassLoader);
992                            }
993    
994                            if ((paclPolicy == null) || !paclPolicy.isActive()) {
995                                    return new TemplateControlContext(null, contextClassLoader);
996                            }
997    
998                            ProtectionDomain protectionDomain = new ProtectionDomain(
999                                    null, null, paclPolicy.getClassLoader(), null);
1000    
1001                            AccessControlContext accessControlContext =
1002                                    new AccessControlContext(
1003                                            new ProtectionDomain[] {protectionDomain});
1004    
1005                            return new TemplateControlContext(
1006                                    accessControlContext, paclPolicy.getClassLoader());
1007                    }
1008    
1009            }
1010    
1011    }