History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/java/security/ProtectionDomain.java (1 of 18352 files). Show all

Unified · Split

java/pkg/java/security/ProtectionDomain.java+467−0
@@ -0,0 +1,467 @@
1/*
2 * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package java.security;
27
28import java.util.ArrayList;
29import java.util.Collections;
30import java.util.Enumeration;
31import java.util.List;
32import java.util.Map;
33import java.util.WeakHashMap;
34import sun.misc.JavaSecurityProtectionDomainAccess;
35import static sun.misc.JavaSecurityProtectionDomainAccess.ProtectionDomainCache;
36import sun.misc.SharedSecrets;
37import sun.security.util.Debug;
38import sun.security.util.SecurityConstants;
39import sun.misc.JavaSecurityAccess;
40import sun.misc.SharedSecrets;
41
42/**
43 *
44 *<p>
45 * This ProtectionDomain class encapsulates the characteristics of a domain,
46 * which encloses a set of classes whose instances are granted a set
47 * of permissions when being executed on behalf of a given set of Principals.
48 * <p>
49 * A static set of permissions can be bound to a ProtectionDomain when it is
50 * constructed; such permissions are granted to the domain regardless of the
51 * Policy in force. However, to support dynamic security policies, a
52 * ProtectionDomain can also be constructed such that it is dynamically
53 * mapped to a set of permissions by the current Policy whenever a permission
54 * is checked.
55 * <p>
56 *
57 * @author Li Gong
58 * @author Roland Schemers
59 * @author Gary Ellison
60 */
61
62public class ProtectionDomain {
63
64 static {
65 // Set up JavaSecurityAccess in SharedSecrets
66 SharedSecrets.setJavaSecurityAccess(
67 new JavaSecurityAccess() {
68 public <T> T doIntersectionPrivilege(
69 PrivilegedAction<T> action,
70 final AccessControlContext stack,
71 final AccessControlContext context)
72 {
73 if (action == null) {
74 throw new NullPointerException();
75 }
76 return AccessController.doPrivileged(
77 action,
78 new AccessControlContext(
79 stack.getContext(), context).optimize()
80 );
81 }
82
83 public <T> T doIntersectionPrivilege(
84 PrivilegedAction<T> action,
85 AccessControlContext context)
86 {
87 return doIntersectionPrivilege(action,
88 AccessController.getContext(), context);
89 }
90 }
91 );
92 }
93
94 /* CodeSource */
95 private CodeSource codesource ;
96
97 /* ClassLoader the protection domain was consed from */
98 private ClassLoader classloader;
99
100 /* Principals running-as within this protection domain */
101 private Principal[] principals;
102
103 /* the rights this protection domain is granted */
104 private PermissionCollection permissions;
105
106 /* if the permissions object has AllPermission */
107 private boolean hasAllPerm = false;
108
109 /* the PermissionCollection is static (pre 1.4 constructor)
110 or dynamic (via a policy refresh) */
111 private boolean staticPermissions;
112
113 /*
114 * An object used as a key when the ProtectionDomain is stored in a Map.
115 */
116 final Key key = new Key();
117
118 private static final Debug debug = Debug.getInstance("domain");
119
120 /**
121 * Creates a new ProtectionDomain with the given CodeSource and
122 * Permissions. If the permissions object is not null, then
123 * <code>setReadOnly())</code> will be called on the passed in
124 * Permissions object. The only permissions granted to this domain
125 * are the ones specified; the current Policy will not be consulted.
126 *
127 * @param codesource the codesource associated with this domain
128 * @param permissions the permissions granted to this domain
129 */
130 public ProtectionDomain(CodeSource codesource,
131 PermissionCollection permissions) {
132 this.codesource = codesource;
133 if (permissions != null) {
134 this.permissions = permissions;
135 this.permissions.setReadOnly();
136 if (permissions instanceof Permissions &&
137 ((Permissions)permissions).allPermission != null) {
138 hasAllPerm = true;
139 }
140 }
141 this.classloader = null;
142 this.principals = new Principal[0];
143 staticPermissions = true;
144 }
145
146 /**
147 * Creates a new ProtectionDomain qualified by the given CodeSource,
148 * Permissions, ClassLoader and array of Principals. If the
149 * permissions object is not null, then <code>setReadOnly()</code>
150 * will be called on the passed in Permissions object.
151 * The permissions granted to this domain are dynamic; they include
152 * both the static permissions passed to this constructor, and any
153 * permissions granted to this domain by the current Policy at the
154 * time a permission is checked.
155 * <p>
156 * This constructor is typically used by
157 * {@link SecureClassLoader ClassLoaders}
158 * and {@link DomainCombiner DomainCombiners} which delegate to
159 * <code>Policy</code> to actively associate the permissions granted to
160 * this domain. This constructor affords the
161 * Policy provider the opportunity to augment the supplied
162 * PermissionCollection to reflect policy changes.
163 * <p>
164 *
165 * @param codesource the CodeSource associated with this domain
166 * @param permissions the permissions granted to this domain
167 * @param classloader the ClassLoader associated with this domain
168 * @param principals the array of Principals associated with this
169 * domain. The contents of the array are copied to protect against
170 * subsequent modification.
171 * @see Policy#refresh
172 * @see Policy#getPermissions(ProtectionDomain)
173 * @since 1.4
174 */
175 public ProtectionDomain(CodeSource codesource,
176 PermissionCollection permissions,
177 ClassLoader classloader,
178 Principal[] principals) {
179 this.codesource = codesource;
180 if (permissions != null) {
181 this.permissions = permissions;
182 this.permissions.setReadOnly();
183 if (permissions instanceof Permissions &&
184 ((Permissions)permissions).allPermission != null) {
185 hasAllPerm = true;
186 }
187 }
188 this.classloader = classloader;
189 this.principals = (principals != null ? principals.clone():
190 new Principal[0]);
191 staticPermissions = false;
192 }
193
194 /**
195 * Returns the CodeSource of this domain.
196 * @return the CodeSource of this domain which may be null.
197 * @since 1.2
198 */
199 public final CodeSource getCodeSource() {
200 return this.codesource;
201 }
202
203
204 /**
205 * Returns the ClassLoader of this domain.
206 * @return the ClassLoader of this domain which may be null.
207 *
208 * @since 1.4
209 */
210 public final ClassLoader getClassLoader() {
211 return this.classloader;
212 }
213
214
215 /**
216 * Returns an array of principals for this domain.
217 * @return a non-null array of principals for this domain.
218 * Returns a new array each time this method is called.
219 *
220 * @since 1.4
221 */
222 public final Principal[] getPrincipals() {
223 return this.principals.clone();
224 }
225
226 /**
227 * Returns the static permissions granted to this domain.
228 *
229 * @return the static set of permissions for this domain which may be null.
230 * @see Policy#refresh
231 * @see Policy#getPermissions(ProtectionDomain)
232 */
233 public final PermissionCollection getPermissions() {
234 return permissions;
235 }
236
237 /**
238 * Check and see if this ProtectionDomain implies the permissions
239 * expressed in the Permission object.
240 * <p>
241 * The set of permissions evaluated is a function of whether the
242 * ProtectionDomain was constructed with a static set of permissions
243 * or it was bound to a dynamically mapped set of permissions.
244 * <p>
245 * If the ProtectionDomain was constructed to a
246 * {@link #ProtectionDomain(CodeSource, PermissionCollection)
247 * statically bound} PermissionCollection then the permission will
248 * only be checked against the PermissionCollection supplied at
249 * construction.
250 * <p>
251 * However, if the ProtectionDomain was constructed with
252 * the constructor variant which supports
253 * {@link #ProtectionDomain(CodeSource, PermissionCollection,
254 * ClassLoader, java.security.Principal[]) dynamically binding}
255 * permissions, then the permission will be checked against the
256 * combination of the PermissionCollection supplied at construction and
257 * the current Policy binding.
258 * <p>
259 *
260 * @param permission the Permission object to check.
261 *
262 * @return true if "permission" is implicit to this ProtectionDomain.
263 */
264 public boolean implies(Permission permission) {
265
266 if (hasAllPerm) {
267 // internal permission collection already has AllPermission -
268 // no need to go to policy
269 return true;
270 }
271
272 if (!staticPermissions &&
273 Policy.getPolicyNoCheck().implies(this, permission))
274 return true;
275 if (permissions != null)
276 return permissions.implies(permission);
277
278 return false;
279 }
280
281 /**
282 * Convert a ProtectionDomain to a String.
283 */
284 @Override public String toString() {
285 String pals = "<no principals>";
286 if (principals != null && principals.length > 0) {
287 StringBuilder palBuf = new StringBuilder("(principals ");
288
289 for (int i = 0; i < principals.length; i++) {
290 palBuf.append(principals[i].getClass().getName() +
291 " \"" + principals[i].getName() +
292 "\"");
293 if (i < principals.length-1)
294 palBuf.append(",\n");
295 else
296 palBuf.append(")\n");
297 }
298 pals = palBuf.toString();
299 }
300
301 // Check if policy is set; we don't want to load
302 // the policy prematurely here
303 PermissionCollection pc = Policy.isSet() && seeAllp() ?
304 mergePermissions():
305 getPermissions();
306
307 return "ProtectionDomain "+
308 " "+codesource+"\n"+
309 " "+classloader+"\n"+
310 " "+pals+"\n"+
311 " "+pc+"\n";
312 }
313
314 /**
315 * Return true (merge policy permissions) in the following cases:
316 *
317 * . SecurityManager is null
318 *
319 * . SecurityManager is not null,
320 * debug is not null,
321 * SecurityManager impelmentation is in bootclasspath,
322 * Policy implementation is in bootclasspath
323 * (the bootclasspath restrictions avoid recursion)
324 *
325 * . SecurityManager is not null,
326 * debug is null,
327 * caller has Policy.getPolicy permission
328 */
329 private static boolean seeAllp() {
330 SecurityManager sm = System.getSecurityManager();
331
332 if (sm == null) {
333 return true;
334 } else {
335 if (debug != null) {
336 if (sm.getClass().getClassLoader() == null &&
337 Policy.getPolicyNoCheck().getClass().getClassLoader()
338 == null) {
339 return true;
340 }
341 } else {
342 try {
343 sm.checkPermission(SecurityConstants.GET_POLICY_PERMISSION);
344 return true;
345 } catch (SecurityException se) {
346 // fall thru and return false
347 }
348 }
349 }
350
351 return false;
352 }
353
354 private PermissionCollection mergePermissions() {
355 if (staticPermissions)
356 return permissions;
357
358 PermissionCollection perms =
359 java.security.AccessController.doPrivileged
360 (new java.security.PrivilegedAction<PermissionCollection>() {
361 public PermissionCollection run() {
362 Policy p = Policy.getPolicyNoCheck();
363 return p.getPermissions(ProtectionDomain.this);
364 }
365 });
366
367 Permissions mergedPerms = new Permissions();
368 int swag = 32;
369 int vcap = 8;
370 Enumeration<Permission> e;
371 List<Permission> pdVector = new ArrayList<>(vcap);
372 List<Permission> plVector = new ArrayList<>(swag);
373
374 //
375 // Build a vector of domain permissions for subsequent merge
376 if (permissions != null) {
377 synchronized (permissions) {
378 e = permissions.elements();
379 while (e.hasMoreElements()) {
380 pdVector.add(e.nextElement());
381 }
382 }
383 }
384
385 //
386 // Build a vector of Policy permissions for subsequent merge
387 if (perms != null) {
388 synchronized (perms) {
389 e = perms.elements();
390 while (e.hasMoreElements()) {
391 plVector.add(e.nextElement());
392 vcap++;
393 }
394 }
395 }
396
397 if (perms != null && permissions != null) {
398 //
399 // Weed out the duplicates from the policy. Unless a refresh
400 // has occured since the pd was consed this should result in
401 // an empty vector.
402 synchronized (permissions) {
403 e = permissions.elements(); // domain vs policy
404 while (e.hasMoreElements()) {
405 Permission pdp = e.nextElement();
406 Class pdpClass = pdp.getClass();
407 String pdpActions = pdp.getActions();
408 String pdpName = pdp.getName();
409 for (int i = 0; i < plVector.size(); i++) {
410 Permission pp = plVector.get(i);
411 if (pdpClass.isInstance(pp)) {
412 // The equals() method on some permissions
413 // have some side effects so this manual
414 // comparison is sufficient.
415 if (pdpName.equals(pp.getName()) &&
416 pdpActions.equals(pp.getActions())) {
417 plVector.remove(i);
418 break;
419 }
420 }
421 }
422 }
423 }
424 }
425
426 if (perms !=null) {
427 // the order of adding to merged perms and permissions
428 // needs to preserve the bugfix 4301064
429
430 for (int i = plVector.size()-1; i >= 0; i--) {
431 mergedPerms.add(plVector.get(i));
432 }
433 }
434 if (permissions != null) {
435 for (int i = pdVector.size()-1; i >= 0; i--) {
436 mergedPerms.add(pdVector.get(i));
437 }
438 }
439
440 return mergedPerms;
441 }
442
443 /**
444 * Used for storing ProtectionDomains as keys in a Map.
445 */
446 final class Key {}
447
448 static {
449 SharedSecrets.setJavaSecurityProtectionDomainAccess(
450 new JavaSecurityProtectionDomainAccess() {
451 public ProtectionDomainCache getProtectionDomainCache() {
452 return new ProtectionDomainCache() {
453 private final Map<Key, PermissionCollection> map =
454 Collections.synchronizedMap
455 (new WeakHashMap<Key, PermissionCollection>());
456 public void put(ProtectionDomain pd,
457 PermissionCollection pc) {
458 map.put((pd == null ? null : pd.key), pc);
459 }
460 public PermissionCollection get(ProtectionDomain pd) {
461 return pd == null ? map.get(null) : map.get(pd.key);
462 }
463 };
464 }
465 });
466 }
467}