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/BasicPermission.java (1 of 18352 files). Show all

Unified · Split

java/pkg/java/security/BasicPermission.java+565−0
@@ -0,0 +1,565 @@
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.security.*;
29+import java.util.Enumeration;
30+import java.util.Map;
31+import java.util.HashMap;
32+import java.util.Hashtable;
33+import java.util.Collections;
34+import java.io.ObjectStreamField;
35+import java.io.ObjectOutputStream;
36+import java.io.ObjectInputStream;
37+import java.io.IOException;
38+
39+/**
40+ * The BasicPermission class extends the Permission class, and
41+ * can be used as the base class for permissions that want to
42+ * follow the same naming convention as BasicPermission.
43+ * <P>
44+ * The name for a BasicPermission is the name of the given permission
45+ * (for example, "exit",
46+ * "setFactory", "print.queueJob", etc). The naming
47+ * convention follows the hierarchical property naming convention.
48+ * An asterisk may appear by itself, or if immediately preceded by a "."
49+ * may appear at the end of the name, to signify a wildcard match.
50+ * For example, "*" and "java.*" are valid, while "*java", "a*b",
51+ * and "java*" are not valid.
52+ * <P>
53+ * The action string (inherited from Permission) is unused.
54+ * Thus, BasicPermission is commonly used as the base class for
55+ * "named" permissions
56+ * (ones that contain a name but no actions list; you either have the
57+ * named permission or you don't.)
58+ * Subclasses may implement actions on top of BasicPermission,
59+ * if desired.
60+ * <p>
61+ * <P>
62+ * @see java.security.Permission
63+ * @see java.security.Permissions
64+ * @see java.security.PermissionCollection
65+ * @see java.lang.SecurityManager
66+ *
67+ * @author Marianne Mueller
68+ * @author Roland Schemers
69+ */
70+
71+public abstract class BasicPermission extends Permission
72+implements java.io.Serializable
73+{
74+
75+ private static final long serialVersionUID = 6279438298436773498L;
76+
77+ // does this permission have a wildcard at the end?
78+ private transient boolean wildcard;
79+
80+ // the name without the wildcard on the end
81+ private transient String path;
82+
83+ // is this permission the old-style exitVM permission (pre JDK 1.6)?
84+ private transient boolean exitVM;
85+
86+ /**
87+ * initialize a BasicPermission object. Common to all constructors.
88+ *
89+ */
90+ private void init(String name)
91+ {
92+ if (name == null)
93+ throw new NullPointerException("name can't be null");
94+
95+ int len = name.length();
96+
97+ if (len == 0) {
98+ throw new IllegalArgumentException("name can't be empty");
99+ }
100+
101+ char last = name.charAt(len - 1);
102+
103+ // Is wildcard or ends with ".*"?
104+ if (last == '*' && (len == 1 || name.charAt(len - 2) == '.')) {
105+ wildcard = true;
106+ if (len == 1) {
107+ path = "";
108+ } else {
109+ path = name.substring(0, len - 1);
110+ }
111+ } else {
112+ if (name.equals("exitVM")) {
113+ wildcard = true;
114+ path = "exitVM.";
115+ exitVM = true;
116+ } else {
117+ path = name;
118+ }
119+ }
120+ }
121+
122+ /**
123+ * Creates a new BasicPermission with the specified name.
124+ * Name is the symbolic name of the permission, such as
125+ * "setFactory",
126+ * "print.queueJob", or "topLevelWindow", etc.
127+ *
128+ * @param name the name of the BasicPermission.
129+ *
130+ * @throws NullPointerException if <code>name</code> is <code>null</code>.
131+ * @throws IllegalArgumentException if <code>name</code> is empty.
132+ */
133+
134+ public BasicPermission(String name)
135+ {
136+ super(name);
137+ init(name);
138+ }
139+
140+
141+ /**
142+ * Creates a new BasicPermission object with the specified name.
143+ * The name is the symbolic name of the BasicPermission, and the
144+ * actions String is currently unused.
145+ *
146+ * @param name the name of the BasicPermission.
147+ * @param actions ignored.
148+ *
149+ * @throws NullPointerException if <code>name</code> is <code>null</code>.
150+ * @throws IllegalArgumentException if <code>name</code> is empty.
151+ */
152+ public BasicPermission(String name, String actions)
153+ {
154+ super(name);
155+ init(name);
156+ }
157+
158+ /**
159+ * Checks if the specified permission is "implied" by
160+ * this object.
161+ * <P>
162+ * More specifically, this method returns true if:<p>
163+ * <ul>
164+ * <li> <i>p</i>'s class is the same as this object's class, and<p>
165+ * <li> <i>p</i>'s name equals or (in the case of wildcards)
166+ * is implied by this object's
167+ * name. For example, "a.b.*" implies "a.b.c".
168+ * </ul>
169+ *
170+ * @param p the permission to check against.
171+ *
172+ * @return true if the passed permission is equal to or
173+ * implied by this permission, false otherwise.
174+ */
175+ public boolean implies(Permission p) {
176+ if ((p == null) || (p.getClass() != getClass()))
177+ return false;
178+
179+ BasicPermission that = (BasicPermission) p;
180+
181+ if (this.wildcard) {
182+ if (that.wildcard) {
183+ // one wildcard can imply another
184+ return that.path.startsWith(path);
185+ } else {
186+ // make sure ap.path is longer so a.b.* doesn't imply a.b
187+ return (that.path.length() > this.path.length()) &&
188+ that.path.startsWith(this.path);
189+ }
190+ } else {
191+ if (that.wildcard) {
192+ // a non-wildcard can't imply a wildcard
193+ return false;
194+ }
195+ else {
196+ return this.path.equals(that.path);
197+ }
198+ }
199+ }
200+
201+ /**
202+ * Checks two BasicPermission objects for equality.
203+ * Checks that <i>obj</i>'s class is the same as this object's class
204+ * and has the same name as this object.
205+ * <P>
206+ * @param obj the object we are testing for equality with this object.
207+ * @return true if <i>obj</i>'s class is the same as this object's class
208+ * and has the same name as this BasicPermission object, false otherwise.
209+ */
210+ public boolean equals(Object obj) {
211+ if (obj == this)
212+ return true;
213+
214+ if ((obj == null) || (obj.getClass() != getClass()))
215+ return false;
216+
217+ BasicPermission bp = (BasicPermission) obj;
218+
219+ return getName().equals(bp.getName());
220+ }
221+
222+
223+ /**
224+ * Returns the hash code value for this object.
225+ * The hash code used is the hash code of the name, that is,
226+ * <code>getName().hashCode()</code>, where <code>getName</code> is
227+ * from the Permission superclass.
228+ *
229+ * @return a hash code value for this object.
230+ */
231+ public int hashCode() {
232+ return this.getName().hashCode();
233+ }
234+
235+ /**
236+ * Returns the canonical string representation of the actions,
237+ * which currently is the empty string "", since there are no actions for
238+ * a BasicPermission.
239+ *
240+ * @return the empty string "".
241+ */
242+ public String getActions()
243+ {
244+ return "";
245+ }
246+
247+ /**
248+ * Returns a new PermissionCollection object for storing BasicPermission
249+ * objects.
250+ *
251+ * <p>BasicPermission objects must be stored in a manner that allows them
252+ * to be inserted in any order, but that also enables the
253+ * PermissionCollection <code>implies</code> method
254+ * to be implemented in an efficient (and consistent) manner.
255+ *
256+ * @return a new PermissionCollection object suitable for
257+ * storing BasicPermissions.
258+ */
259+ public PermissionCollection newPermissionCollection() {
260+ return new BasicPermissionCollection(this.getClass());
261+ }
262+
263+ /**
264+ * readObject is called to restore the state of the BasicPermission from
265+ * a stream.
266+ */
267+ private void readObject(ObjectInputStream s)
268+ throws IOException, ClassNotFoundException
269+ {
270+ s.defaultReadObject();
271+ // init is called to initialize the rest of the values.
272+ init(getName());
273+ }
274+
275+ /**
276+ * Returns the canonical name of this BasicPermission.
277+ * All internal invocations of getName should invoke this method, so
278+ * that the pre-JDK 1.6 "exitVM" and current "exitVM.*" permission are
279+ * equivalent in equals/hashCode methods.
280+ *
281+ * @return the canonical name of this BasicPermission.
282+ */
283+ final String getCanonicalName() {
284+ return exitVM ? "exitVM.*" : getName();
285+ }
286+}
287+
288+/**
289+ * A BasicPermissionCollection stores a collection
290+ * of BasicPermission permissions. BasicPermission objects
291+ * must be stored in a manner that allows them to be inserted in any
292+ * order, but enable the implies function to evaluate the implies
293+ * method in an efficient (and consistent) manner.
294+ *
295+ * A BasicPermissionCollection handles comparing a permission like "a.b.c.d.e"
296+ * with a Permission such as "a.b.*", or "*".
297+ *
298+ * @see java.security.Permission
299+ * @see java.security.Permissions
300+ * @see java.security.PermissionsImpl
301+ *
302+ *
303+ * @author Roland Schemers
304+ *
305+ * @serial include
306+ */
307+
308+final class BasicPermissionCollection
309+extends PermissionCollection
310+implements java.io.Serializable
311+{
312+
313+ private static final long serialVersionUID = 739301742472979399L;
314+
315+ /**
316+ * Key is name, value is permission. All permission objects in
317+ * collection must be of the same type.
318+ * Not serialized; see serialization section at end of class.
319+ */
320+ private transient Map<String, Permission> perms;
321+
322+ /**
323+ * This is set to <code>true</code> if this BasicPermissionCollection
324+ * contains a BasicPermission with '*' as its permission name.
325+ *
326+ * @see #serialPersistentFields
327+ */
328+ private boolean all_allowed;
329+
330+ /**
331+ * The class to which all BasicPermissions in this
332+ * BasicPermissionCollection belongs.
333+ *
334+ * @see #serialPersistentFields
335+ */
336+ private Class permClass;
337+
338+ /**
339+ * Create an empty BasicPermissionCollection object.
340+ *
341+ */
342+
343+ public BasicPermissionCollection(Class clazz) {
344+ perms = new HashMap<String, Permission>(11);
345+ all_allowed = false;
346+ permClass = clazz;
347+ }
348+
349+ /**
350+ * Adds a permission to the BasicPermissions. The key for the hash is
351+ * permission.path.
352+ *
353+ * @param permission the Permission object to add.
354+ *
355+ * @exception IllegalArgumentException - if the permission is not a
356+ * BasicPermission, or if
357+ * the permission is not of the
358+ * same Class as the other
359+ * permissions in this collection.
360+ *
361+ * @exception SecurityException - if this BasicPermissionCollection object
362+ * has been marked readonly
363+ */
364+
365+ public void add(Permission permission)
366+ {
367+ if (! (permission instanceof BasicPermission))
368+ throw new IllegalArgumentException("invalid permission: "+
369+ permission);
370+ if (isReadOnly())
371+ throw new SecurityException("attempt to add a Permission to a readonly PermissionCollection");
372+
373+ BasicPermission bp = (BasicPermission) permission;
374+
375+ // make sure we only add new BasicPermissions of the same class
376+ // Also check null for compatibility with deserialized form from
377+ // previous versions.
378+ if (permClass == null) {
379+ // adding first permission
380+ permClass = bp.getClass();
381+ } else {
382+ if (bp.getClass() != permClass)
383+ throw new IllegalArgumentException("invalid permission: " +
384+ permission);
385+ }
386+
387+ synchronized (this) {
388+ perms.put(bp.getCanonicalName(), permission);
389+ }
390+
391+ // No sync on all_allowed; staleness OK
392+ if (!all_allowed) {
393+ if (bp.getCanonicalName().equals("*"))
394+ all_allowed = true;
395+ }
396+ }
397+
398+ /**
399+ * Check and see if this set of permissions implies the permissions
400+ * expressed in "permission".
401+ *
402+ * @param p the Permission object to compare
403+ *
404+ * @return true if "permission" is a proper subset of a permission in
405+ * the set, false if not.
406+ */
407+
408+ public boolean implies(Permission permission)
409+ {
410+ if (! (permission instanceof BasicPermission))
411+ return false;
412+
413+ BasicPermission bp = (BasicPermission) permission;
414+
415+ // random subclasses of BasicPermission do not imply each other
416+ if (bp.getClass() != permClass)
417+ return false;
418+
419+ // short circuit if the "*" Permission was added
420+ if (all_allowed)
421+ return true;
422+
423+ // strategy:
424+ // Check for full match first. Then work our way up the
425+ // path looking for matches on a.b..*
426+
427+ String path = bp.getCanonicalName();
428+ //System.out.println("check "+path);
429+
430+ Permission x;
431+
432+ synchronized (this) {
433+ x = perms.get(path);
434+ }
435+
436+ if (x != null) {
437+ // we have a direct hit!
438+ return x.implies(permission);
439+ }
440+
441+ // work our way up the tree...
442+ int last, offset;
443+
444+ offset = path.length()-1;
445+
446+ while ((last = path.lastIndexOf(".", offset)) != -1) {
447+
448+ path = path.substring(0, last+1) + "*";
449+ //System.out.println("check "+path);
450+
451+ synchronized (this) {
452+ x = perms.get(path);
453+ }
454+
455+ if (x != null) {
456+ return x.implies(permission);
457+ }
458+ offset = last -1;
459+ }
460+
461+ // we don't have to check for "*" as it was already checked
462+ // at the top (all_allowed), so we just return false
463+ return false;
464+ }
465+
466+ /**
467+ * Returns an enumeration of all the BasicPermission objects in the
468+ * container.
469+ *
470+ * @return an enumeration of all the BasicPermission objects.
471+ */
472+
473+ public Enumeration<Permission> elements() {
474+ // Convert Iterator of Map values into an Enumeration
475+ synchronized (this) {
476+ return Collections.enumeration(perms.values());
477+ }
478+ }
479+
480+ // Need to maintain serialization interoperability with earlier releases,
481+ // which had the serializable field:
482+ //
483+ // @serial the Hashtable is indexed by the BasicPermission name
484+ //
485+ // private Hashtable permissions;
486+ /**
487+ * @serialField permissions java.util.Hashtable
488+ * The BasicPermissions in this BasicPermissionCollection.
489+ * All BasicPermissions in the collection must belong to the same class.
490+ * The Hashtable is indexed by the BasicPermission name; the value
491+ * of the Hashtable entry is the permission.
492+ * @serialField all_allowed boolean
493+ * This is set to <code>true</code> if this BasicPermissionCollection
494+ * contains a BasicPermission with '*' as its permission name.
495+ * @serialField permClass java.lang.Class
496+ * The class to which all BasicPermissions in this
497+ * BasicPermissionCollection belongs.
498+ */
499+ private static final ObjectStreamField[] serialPersistentFields = {
500+ new ObjectStreamField("permissions", Hashtable.class),
501+ new ObjectStreamField("all_allowed", Boolean.TYPE),
502+ new ObjectStreamField("permClass", Class.class),
503+ };
504+
505+ /**
506+ * @serialData Default fields.
507+ */
508+ /*
509+ * Writes the contents of the perms field out as a Hashtable for
510+ * serialization compatibility with earlier releases. all_allowed
511+ * and permClass unchanged.
512+ */
513+ private void writeObject(ObjectOutputStream out) throws IOException {
514+ // Don't call out.defaultWriteObject()
515+
516+ // Copy perms into a Hashtable
517+ Hashtable<String, Permission> permissions =
518+ new Hashtable<>(perms.size()*2);
519+
520+ synchronized (this) {
521+ permissions.putAll(perms);
522+ }
523+
524+ // Write out serializable fields
525+ ObjectOutputStream.PutField pfields = out.putFields();
526+ pfields.put("all_allowed", all_allowed);
527+ pfields.put("permissions", permissions);
528+ pfields.put("permClass", permClass);
529+ out.writeFields();
530+ }
531+
532+ /**
533+ * readObject is called to restore the state of the
534+ * BasicPermissionCollection from a stream.
535+ */
536+ private void readObject(java.io.ObjectInputStream in)
537+ throws IOException, ClassNotFoundException
538+ {
539+ // Don't call defaultReadObject()
540+
541+ // Read in serialized fields
542+ ObjectInputStream.GetField gfields = in.readFields();
543+
544+ // Get permissions
545+ Hashtable<String, Permission> permissions =
546+ (Hashtable<String, Permission>)gfields.get("permissions", null);
547+ perms = new HashMap<String, Permission>(permissions.size()*2);
548+ perms.putAll(permissions);
549+
550+ // Get all_allowed
551+ all_allowed = gfields.get("all_allowed", false);
552+
553+ // Get permClass
554+ permClass = (Class) gfields.get("permClass", null);
555+
556+ if (permClass == null) {
557+ // set permClass
558+ Enumeration<Permission> e = permissions.elements();
559+ if (e.hasMoreElements()) {
560+ Permission p = e.nextElement();
561+ permClass = p.getClass();
562+ }
563+ }
564+ }
565+}