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.kernel.cache.CacheRegistryItem;
018    import com.liferay.portal.kernel.util.ProxyUtil;
019    import com.liferay.portal.security.lang.PortalSecurityManager;
020    import com.liferay.portal.security.lang.SecurityManagerUtil;
021    
022    import java.security.AccessController;
023    import java.security.BasicPermission;
024    import java.security.PermissionCollection;
025    import java.security.Policy;
026    import java.security.PrivilegedAction;
027    import java.security.ProtectionDomain;
028    
029    /**
030     * @author Raymond Augé
031     */
032    public class PACLUtil {
033    
034            public static Class<?> getClass(Object object) {
035                    Class<?> clazz = object.getClass();
036    
037                    if (object instanceof Class) {
038                            clazz = (Class<?>)object;
039                    }
040    
041                    if (ProxyUtil.isProxyClass(clazz) || !clazz.isInterface()) {
042                            Class<?>[] interfaces = clazz.getInterfaces();
043    
044                            if (interfaces.length > 0) {
045                                    clazz = interfaces[0];
046    
047                                    if (clazz.equals(CacheRegistryItem.class) &&
048                                            (interfaces.length > 1)) {
049    
050                                            clazz = interfaces[1];
051                                    }
052                            }
053                    }
054    
055                    return clazz;
056            }
057    
058            public static PACLPolicy getPACLPolicy() {
059                    if (!PACLPolicyManager.isActive()) {
060                            return null;
061                    }
062    
063                    SecurityManager securityManager = System.getSecurityManager();
064    
065                    if (securityManager == null) {
066                            return null;
067                    }
068    
069                    try {
070                            java.security.Permission permission = new PACLUtil.Permission();
071    
072                            securityManager.checkPermission(permission);
073                    }
074                    catch (SecurityException se) {
075                            if (!(se instanceof PACLUtil.Exception)) {
076                                    throw se;
077                            }
078    
079                            PACLUtil.Exception paclUtilException = (PACLUtil.Exception)se;
080    
081                            return paclUtilException.getPaclPolicy();
082                    }
083    
084                    return null;
085            }
086    
087            public static String getServiceInterfaceName(String serviceClassName) {
088                    int pos = serviceClassName.indexOf(".impl.");
089    
090                    if (pos != -1) {
091                            serviceClassName =
092                                    serviceClassName.substring(0, pos + 1) +
093                                            serviceClassName.substring(pos + 6);
094                    }
095    
096                    if (serviceClassName.endsWith("Impl")) {
097                            serviceClassName = serviceClassName.substring(
098                                    0, serviceClassName.length() - 4);
099                    }
100    
101                    return serviceClassName;
102            }
103    
104            public static boolean isTrustedCaller(
105                    Class<?> callerClass, java.security.Permission permission,
106                    PACLPolicy paclPolicy) {
107    
108                    ProtectionDomain protectionDomain = AccessController.doPrivileged(
109                            new ProtectionDomainPrivilegedAction(callerClass));
110    
111                    return _isTrustedCaller(protectionDomain, permission, paclPolicy);
112            }
113    
114            public static class Exception extends SecurityException {
115    
116                    public Exception(PACLPolicy paclPolicy) {
117                            _paclPolicy = paclPolicy;
118                    }
119    
120                    public PACLPolicy getPaclPolicy() {
121                            return _paclPolicy;
122                    }
123    
124                    private PACLPolicy _paclPolicy;
125    
126            }
127    
128            public static class Permission extends BasicPermission {
129    
130                    public Permission() {
131                            super("getPACLPolicy");
132                    }
133    
134            }
135    
136            private static boolean _hasSameOrigin(
137                    ProtectionDomain protectionDomain,
138                    PermissionCollection permissionCollection, PACLPolicy paclPolicy) {
139    
140                    PACLPolicy callerPACLPolicy = null;
141    
142                    if (permissionCollection instanceof PortalPermissionCollection) {
143                            PortalPermissionCollection portalPermissionCollection =
144                                    (PortalPermissionCollection)permissionCollection;
145    
146                            callerPACLPolicy = portalPermissionCollection.getPACLPolicy();
147                    }
148                    else {
149                            callerPACLPolicy = PACLPolicyManager.getPACLPolicy(
150                                    protectionDomain.getClassLoader());
151                    }
152    
153                    if (paclPolicy == callerPACLPolicy) {
154                            return true;
155                    }
156    
157                    return false;
158            }
159    
160            private static boolean _isTrustedCaller(
161                    ProtectionDomain protectionDomain, java.security.Permission permission,
162                    PACLPolicy paclPolicy) {
163    
164                    if (protectionDomain.getClassLoader() == null) {
165                            return true;
166                    }
167    
168                    PortalSecurityManager portalSecurityManager =
169                            SecurityManagerUtil.getPortalSecurityManager();
170    
171                    Policy portalPolicy = portalSecurityManager.getPolicy();
172    
173                    PermissionCollection permissionCollection = portalPolicy.getPermissions(
174                            protectionDomain);
175    
176                    if (!_hasSameOrigin(
177                                    protectionDomain, permissionCollection, paclPolicy) &&
178                            permissionCollection.implies(permission)) {
179    
180                            return true;
181                    }
182    
183                    return false;
184            }
185    
186            private static class ProtectionDomainPrivilegedAction
187                    implements PrivilegedAction<ProtectionDomain> {
188    
189                    public ProtectionDomainPrivilegedAction(Class<?> clazz) {
190                            _clazz = clazz;
191                    }
192    
193                    public ProtectionDomain run() {
194                            return _clazz.getProtectionDomain();
195                    }
196    
197                    private Class<?> _clazz;
198    
199            }
200    
201    }