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+
26+package java.security;
27+
28+import java.util.ArrayList;
29+import java.util.Collections;
30+import java.util.Enumeration;
31+import java.util.List;
32+import java.util.Map;
33+import java.util.WeakHashMap;
34+import sun.misc.JavaSecurityProtectionDomainAccess;
35+import static sun.misc.JavaSecurityProtectionDomainAccess.ProtectionDomainCache;
36+import sun.misc.SharedSecrets;
37+import sun.security.util.Debug;
38+import sun.security.util.SecurityConstants;
39+import sun.misc.JavaSecurityAccess;
40+import 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+
62+public 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+}