001
014
015 package com.liferay.portal.security.pacl.checker;
016
017 import com.liferay.portal.kernel.log.Log;
018 import com.liferay.portal.kernel.log.LogFactoryUtil;
019 import com.liferay.portal.kernel.util.StringPool;
020
021 import java.security.Permission;
022
023 import java.util.ArrayList;
024 import java.util.List;
025 import java.util.Set;
026 import java.util.regex.Matcher;
027 import java.util.regex.Pattern;
028
029 import sun.reflect.Reflection;
030
031
035 public class RuntimeChecker extends BaseChecker {
036
037 public void afterPropertiesSet() {
038 initEnvironmentVariables();
039 }
040
041 @Override
042 public AuthorizationProperty generateAuthorizationProperty(
043 Object... arguments) {
044
045 if ((arguments == null) || (arguments.length != 1) ||
046 !(arguments[0] instanceof Permission)) {
047
048 return null;
049 }
050
051 Permission permission = (Permission)arguments[0];
052
053 String name = permission.getName();
054
055 String key = null;
056 String value = null;
057
058 if (name.startsWith(RUNTIME_PERMISSION_GET_ENV)) {
059 key = "security-manager-environment-variables";
060
061 value = name.substring(RUNTIME_PERMISSION_GET_ENV.length() + 1);
062
063
064
065
066 if (value.equals(StringPool.STAR)) {
067 value = StringPool.DOUBLE_BACK_SLASH + value;
068 }
069 }
070 else {
071 return null;
072 }
073
074 AuthorizationProperty authorizationProperty =
075 new AuthorizationProperty();
076
077 authorizationProperty.setKey(key);
078 authorizationProperty.setValue(value);
079
080 return authorizationProperty;
081 }
082
083 public boolean implies(Permission permission) {
084 String name = permission.getName();
085
086 if (name.startsWith(RUNTIME_PERMISSION_ACCESS_CLASS_IN_PACKAGE)) {
087 int pos = name.indexOf(StringPool.PERIOD);
088
089 String pkg = name.substring(pos + 1);
090
091 if (!hasAccessClassInPackage(pkg)) {
092 logSecurityException(
093 _log, "Attempted to access package " + pkg);
094
095 return false;
096 }
097 }
098 else if (name.equals(RUNTIME_PERMISSION_ACCESS_DECLARED_MEMBERS)) {
099 if (!hasReflect(permission)) {
100 logSecurityException(
101 _log, "Attempted to access declared members");
102
103 return false;
104 }
105 }
106 else if (name.equals(RUNTIME_PERMISSION_CREATE_CLASS_LOADER)) {
107 if (!hasCreateClassLoader(permission)) {
108 logSecurityException(
109 _log, "Attempted to create a class loader");
110
111 return false;
112 }
113 }
114 else if (name.equals(RUNTIME_PERMISSION_CREATE_SECURITY_MANAGER)) {
115 if (!hasCreateSecurityManager(permission)) {
116 logSecurityException(
117 _log, "Attempted to create a security manager");
118
119 return false;
120 }
121 }
122 else if (name.startsWith(RUNTIME_PERMISSION_GET_CLASSLOADER)) {
123 if (!hasGetClassLoader(permission)) {
124 logSecurityException(_log, "Attempted to get class loader");
125
126 return false;
127 }
128 }
129 else if (name.startsWith(RUNTIME_PERMISSION_GET_PROTECTION_DOMAIN)) {
130 if (!hasGetProtectionDomain(permission)) {
131 logSecurityException(
132 _log, "Attempted to get protection domain");
133
134 return false;
135 }
136 }
137 else if (name.startsWith(RUNTIME_PERMISSION_GET_ENV)) {
138 int pos = name.indexOf(StringPool.PERIOD);
139
140 String envName = name.substring(pos + 1);
141
142 if (!hasGetEnv(envName, permission)) {
143 logSecurityException(
144 _log, "Attempted to get environment name " + envName);
145
146 return false;
147 }
148 }
149 else if (name.startsWith(RUNTIME_PERMISSION_LOAD_LIBRARY)) {
150 if (!hasLoadLibrary(permission)) {
151 logSecurityException(_log, "Attempted to load library");
152
153 return false;
154 }
155 }
156 else if (name.equals(RUNTIME_PERMISSION_READ_FILE_DESCRIPTOR)) {
157 if (!hasReadFileDescriptor(permission)) {
158 logSecurityException(_log, "Attempted to read file descriptor");
159
160 return false;
161 }
162 }
163 else if (name.equals(RUNTIME_PERMISSION_SET_CONTEXT_CLASS_LOADER)) {
164 if (!hasSetContextClassLoader(permission)) {
165 logSecurityException(
166 _log, "Attempted to set the context class loader");
167
168 return false;
169 }
170 }
171 else if (name.equals(RUNTIME_PERMISSION_SET_SECURITY_MANAGER)) {
172 logSecurityException(
173 _log, "Attempted to set another security manager");
174
175 return false;
176 }
177 else if (name.equals(RUNTIME_PERMISSION_WRITE_FILE_DESCRIPTOR)) {
178 if (!hasWriteFileDescriptor(permission)) {
179 logSecurityException(
180 _log, "Attempted to write file descriptor");
181
182 return false;
183 }
184 }
185 else {
186 if (_log.isDebugEnabled()) {
187 Thread.dumpStack();
188 }
189
190 logSecurityException(
191 _log, "Attempted to " + permission.getName() + " on " +
192 permission.getActions());
193
194 return false;
195 }
196
197 return true;
198 }
199
200 protected boolean hasAccessClassInPackage(String pkg) {
201
202
203
204 if (pkg.startsWith("sun.reflect")) {
205 }
206
207 return true;
208 }
209
210 protected boolean hasCreateClassLoader(Permission permission) {
211 int stackIndex = getStackIndex(15, 11);
212
213 Class<?> callerClass = Reflection.getCallerClass(stackIndex);
214
215 if (isTrustedCaller(callerClass, permission)) {
216 return true;
217 }
218
219 return false;
220 }
221
222 protected boolean hasCreateSecurityManager(Permission permission) {
223 int stackIndex = getStackIndex(11, 10);
224
225 Class<?> callerClass = Reflection.getCallerClass(stackIndex);
226
227 if (isTrustedCaller(callerClass, permission)) {
228 return true;
229 }
230
231 return false;
232 }
233
234 protected boolean hasGetClassLoader(Permission permission) {
235 int stackIndex = getStackIndex(11, 10);
236
237 Class<?> callerClass = Reflection.getCallerClass(stackIndex);
238
239 if (isTrustedCaller(callerClass, permission)) {
240 return true;
241 }
242
243 return false;
244 }
245
246 protected boolean hasGetEnv(String name, Permission permission) {
247 for (Pattern environmentVariablePattern :
248 _environmentVariablePatterns) {
249
250 Matcher matcher = environmentVariablePattern.matcher(name);
251
252 if (matcher.matches()) {
253 return true;
254 }
255 }
256
257 int stackIndex = getStackIndex(11, 10);
258
259 Class<?> callerClass = Reflection.getCallerClass(stackIndex);
260
261 if (isTrustedCaller(callerClass, permission)) {
262 return true;
263 }
264
265 return false;
266 }
267
268 protected boolean hasGetProtectionDomain(Permission permission) {
269 int stackIndex = getStackIndex(11, 10);
270
271 Class<?> callerClass = Reflection.getCallerClass(stackIndex);
272
273 if (isTrustedCaller(callerClass, permission)) {
274 return true;
275 }
276
277 return false;
278 }
279
280 protected boolean hasLoadLibrary(Permission permission) {
281 int stackIndex = getStackIndex(13, 12);
282
283 Class<?> callerClass = Reflection.getCallerClass(stackIndex);
284
285 if (isTrustedCaller(callerClass, permission)) {
286 return true;
287 }
288
289 return false;
290 }
291
292 protected boolean hasReadFileDescriptor(Permission permission) {
293 int stackIndex = getStackIndex(12, 11);
294
295 Class<?> callerClass = Reflection.getCallerClass(stackIndex);
296
297 if (isTrustedCaller(callerClass, permission)) {
298 return true;
299 }
300
301 return false;
302 }
303
304 protected boolean hasReflect(Permission permission) {
305 int stackIndex = getStackIndex(13, 12);
306
307 Class<?> callerClass = Reflection.getCallerClass(stackIndex);
308
309 if (isTrustedCaller(callerClass, permission)) {
310 return true;
311 }
312
313 return false;
314 }
315
316 protected boolean hasSetContextClassLoader(Permission permission) {
317 int stackIndex = getStackIndex(11, 10);
318
319 Class<?> callerClass = Reflection.getCallerClass(stackIndex);
320
321 if (isTrustedCaller(callerClass, permission)) {
322 return true;
323 }
324
325 return false;
326 }
327
328 protected boolean hasWriteFileDescriptor(Permission permission) {
329 int stackIndex = getStackIndex(12, 11);
330
331 Class<?> callerClass = Reflection.getCallerClass(stackIndex);
332
333 if (isTrustedCaller(callerClass, permission)) {
334 return true;
335 }
336
337 return false;
338 }
339
340 protected void initEnvironmentVariables() {
341 Set<String> environmentVariables = getPropertySet(
342 "security-manager-environment-variables");
343
344 _environmentVariablePatterns = new ArrayList<Pattern>(
345 environmentVariables.size());
346
347 for (String environmentVariable : environmentVariables) {
348 Pattern environmentVariablePattern = Pattern.compile(
349 environmentVariable);
350
351 _environmentVariablePatterns.add(environmentVariablePattern);
352
353 if (_log.isDebugEnabled()) {
354 _log.debug(
355 "Allowing access to environment variables that match " +
356 "the regular expression " + environmentVariable);
357 }
358 }
359 }
360
361 private static Log _log = LogFactoryUtil.getLog(RuntimeChecker.class);
362
363 private List<Pattern> _environmentVariablePatterns;
364
365 }