001
014
015 package com.liferay.portal.security.pacl;
016
017 import com.liferay.portal.kernel.log.Log;
018 import com.liferay.portal.kernel.log.LogFactoryUtil;
019 import com.liferay.portal.kernel.util.FileUtil;
020 import com.liferay.portal.kernel.util.StringBundler;
021 import com.liferay.portal.kernel.util.StringPool;
022 import com.liferay.portal.security.lang.PortalSecurityManagerThreadLocal;
023 import com.liferay.portal.security.pacl.checker.AuthorizationProperty;
024 import com.liferay.portal.security.pacl.checker.Checker;
025 import com.liferay.portal.security.pacl.checker.JNDIChecker;
026 import com.liferay.portal.security.pacl.checker.PortalServiceChecker;
027 import com.liferay.portal.security.pacl.checker.SQLChecker;
028 import com.liferay.portal.util.PropsValues;
029
030 import java.io.IOException;
031
032 import java.lang.reflect.Method;
033
034 import java.security.Permission;
035
036 import java.util.Enumeration;
037 import java.util.Map;
038 import java.util.Properties;
039 import java.util.Set;
040 import java.util.concurrent.ConcurrentSkipListMap;
041 import java.util.concurrent.locks.ReentrantLock;
042
043
046 public class GeneratingPACLPolicy extends ActivePACLPolicy {
047
048 public GeneratingPACLPolicy(
049 String servletContextName, ClassLoader classLoader,
050 Properties properties) {
051
052 super(servletContextName, classLoader, properties);
053 }
054
055 @Override
056 public void checkPermission(Permission permission) {
057 Checker checker = getChecker(permission.getClass());
058
059 try {
060 checker.checkPermission(permission);
061 }
062 catch (SecurityException se) {
063 try {
064 AuthorizationProperty authorizationProperty =
065 checker.generateAuthorizationProperty(permission);
066
067 mergeAuthorizationProperty(authorizationProperty);
068 }
069 catch (Exception e) {
070 throw se;
071 }
072 }
073 }
074
075 @Override
076 public boolean hasJNDI(String name) {
077 JNDIChecker jndiChecker = getJndiChecker();
078
079 if (!jndiChecker.hasJNDI(name)) {
080 AuthorizationProperty authorizationProperty =
081 jndiChecker.generateAuthorizationProperty(name);
082
083 mergeAuthorizationProperty(authorizationProperty);
084 }
085
086 return true;
087 }
088
089 @Override
090 public boolean hasPortalService(
091 Object object, Method method, Object[] arguments) {
092
093 PortalServiceChecker portalServiceChecker = getPortalServiceChecker();
094
095 if (!portalServiceChecker.hasService(object, method, arguments)) {
096 AuthorizationProperty authorizationProperty =
097 portalServiceChecker.generateAuthorizationProperty(
098 object, method, arguments);
099
100 mergeAuthorizationProperty(authorizationProperty);
101 }
102
103 return true;
104 }
105
106 @Override
107 public boolean hasSQL(String sql) {
108 SQLChecker sqlChecker = getSqlChecker();
109
110 if (!sqlChecker.hasSQL(sql)) {
111 AuthorizationProperty authorizationProperty =
112 sqlChecker.generateAuthorizationProperty(sql);
113
114 mergeAuthorizationProperty(authorizationProperty);
115 }
116
117 return true;
118 }
119
120 protected void mergeAuthorizationProperty(
121 AuthorizationProperty authorizationProperty) {
122
123 if (authorizationProperty == null) {
124 return;
125 }
126
127 String key = authorizationProperty.getKey();
128
129 Set<String> values = _properties.get(key);
130
131 boolean modified = false;
132
133 if (values == null) {
134 values = getPropertySet(key);
135
136 modified = true;
137 }
138
139 for (String value : authorizationProperty.getValues()) {
140 if (!values.contains(value)) {
141 values.add(value);
142
143 modified = true;
144 }
145 }
146
147 if (!modified) {
148 return;
149 }
150
151 _reentrantLock.lock();
152
153 try {
154 if (_log.isDebugEnabled()) {
155 _log.debug(
156 getServletContextName() +
157 " generated authorization property " +
158 authorizationProperty);
159 }
160
161 _properties.put(key, values);
162
163 mergeExistingProperties();
164
165 writePACLPolicyFile();
166 }
167 finally {
168 _reentrantLock.unlock();
169 }
170 }
171
172 protected void mergeExistingProperties() {
173
174
175
176
177
178 Properties properties = getProperties();
179
180 Enumeration<Object> enumeration = properties.keys();
181
182 while (enumeration.hasMoreElements()) {
183 String key = (String)enumeration.nextElement();
184
185 if (_properties.containsKey(key) ||
186 !key.startsWith("security-manager-") ||
187 key.equals("security-manager-enabled")) {
188
189 continue;
190 }
191
192 _properties.put(key, getPropertySet(key));
193 }
194 }
195
196 protected void writePACLPolicyFile() {
197 boolean enabled = PortalSecurityManagerThreadLocal.isEnabled();
198
199 try {
200 PortalSecurityManagerThreadLocal.setEnabled(false);
201
202 StringBundler sb = new StringBundler();
203
204 for (Map.Entry<String, Set<String>> entry :
205 _properties.entrySet()) {
206
207 String key = entry.getKey();
208
209 sb.append(key);
210 sb.append(StringPool.EQUAL);
211
212 Set<String> values = entry.getValue();
213
214 for (String value : values) {
215 sb.append(StringPool.BACK_SLASH);
216 sb.append(StringPool.NEW_LINE);
217 sb.append(StringPool.FOUR_SPACES);
218 sb.append(value);
219 sb.append(StringPool.COMMA);
220 }
221
222 sb.setIndex(sb.index() - 1);
223
224 sb.append(StringPool.NEW_LINE + StringPool.NEW_LINE);
225 }
226
227 if (sb.length() > 0) {
228 sb.setIndex(sb.index() - 1);
229 }
230
231 FileUtil.write(
232 PropsValues.LIFERAY_HOME + "/pacl-policy",
233 getServletContextName() + ".pacl-policy", sb.toString());
234 }
235 catch (IOException ioe) {
236 _log.error(ioe, ioe);
237 }
238 finally {
239 PortalSecurityManagerThreadLocal.setEnabled(enabled);
240 }
241 }
242
243 private static Log _log = LogFactoryUtil.getLog(GeneratingPACLPolicy.class);
244
245 private Map<String, Set<String>> _properties =
246 new ConcurrentSkipListMap<String, Set<String>>();
247 private ReentrantLock _reentrantLock = new ReentrantLock();
248
249 }