1 |
/* java.util.PropertyPermission |
/* PropertyPermission.java -- permission to get and set System properties |
2 |
Copyright (C) 1999, 2000 Free Software Foundation, Inc. |
Copyright (C) 1999, 2000, 2002 Free Software Foundation, Inc. |
3 |
|
|
4 |
This file is part of GNU Classpath. |
This file is part of GNU Classpath. |
5 |
|
|
37 |
|
|
38 |
|
|
39 |
package java.util; |
package java.util; |
40 |
|
|
41 |
import java.security.Permission; |
import java.security.Permission; |
42 |
import java.security.BasicPermission; |
import java.security.BasicPermission; |
43 |
import java.security.PermissionCollection; |
import java.security.PermissionCollection; |
50 |
* This class represents the permission to access and modify a property.<br> |
* This class represents the permission to access and modify a property.<br> |
51 |
* |
* |
52 |
* The name is the name of the property, e.g. xxx. You can also |
* The name is the name of the property, e.g. xxx. You can also |
53 |
* use an asterisk "*" as described in BasicPermission <br> |
* use an asterisk "*" as described in BasicPermission.<br> |
54 |
* |
* |
55 |
* The action string is a comma-separated list if keywords. There are |
* The action string is a comma-separated list of keywords. There are |
56 |
* two possible actions: |
* two possible actions: |
57 |
* <dl> |
* <dl> |
58 |
* <dt>read</dt> |
* <dt>read</dt> |
59 |
* <dd>Allows to read the property via <code>System.getProperty</code>.</dd> |
* <dd>Allows to read the property via <code>System.getProperty</code>.</dd> |
60 |
* <dt>write</dt> |
* <dt>write</dt> |
61 |
* <dd>Allows to write the property via <code>System.setProperty</code>.</dd> |
* <dd>Allows to write the property via <code>System.setProperty</code>.</dd> |
62 |
* </dl> |
* </dl> |
63 |
* |
* |
64 |
* The action string is case insensitive (it is converted to lower case). |
* The action string is case insensitive (it is converted to lower case). |
65 |
* |
* |
66 |
* @see Permission |
* @see Permission |
67 |
* @see BasicPermission |
* @see BasicPermission |
68 |
* @author Jochen Hoenicke |
* @see SecurityManager |
69 |
|
* @author Jochen Hoenicke |
70 |
|
* @since 1.2 |
71 |
|
* @status updated to 1.4 |
72 |
*/ |
*/ |
73 |
public final class PropertyPermission extends BasicPermission |
public final class PropertyPermission extends BasicPermission |
74 |
{ |
{ |
75 |
/** |
/** |
76 |
* @serialField action String |
* PropertyPermission uses a more efficient representation than the |
77 |
* The action string. |
* serialized form; this documents the difference. |
78 |
|
* |
79 |
|
* @serialField action String the action string |
80 |
*/ |
*/ |
81 |
private static final ObjectStreamField[] serialPersistentFields = |
private static final ObjectStreamField[] serialPersistentFields = |
82 |
{ |
{ |
83 |
new ObjectStreamField("action", String.class) |
new ObjectStreamField("action", String.class) |
84 |
}; |
}; |
85 |
|
|
86 |
|
/** |
87 |
|
* Compatible with JDK 1.2+. |
88 |
|
*/ |
89 |
private static final long serialVersionUID = 885438825399942851L; |
private static final long serialVersionUID = 885438825399942851L; |
90 |
|
|
91 |
|
/** Permission to read. */ |
92 |
private static final int READ = 1; |
private static final int READ = 1; |
93 |
|
/** Permission to write. */ |
94 |
private static final int WRITE = 2; |
private static final int WRITE = 2; |
95 |
|
|
96 |
|
/** The set of actions permitted. */ |
97 |
private transient int actions; |
private transient int actions; |
98 |
|
|
99 |
|
/** |
100 |
|
* The String forms of the actions permitted. |
101 |
|
*/ |
102 |
private static final String actionStrings[] = |
private static final String actionStrings[] = |
103 |
{ |
{ |
104 |
"", "read", "write", "read,write" |
"", "read", "write", "read,write" |
105 |
}; |
}; |
106 |
|
|
107 |
/** |
/** |
108 |
* Constructs a PropertyPermission witha he specified property. Possible |
* Constructs a PropertyPermission with the specified property. Possible |
109 |
* actions are read and write. |
* actions are read and write. |
110 |
* @param name the name of the property. |
* |
111 |
* @param actions the action string. |
* @param name the name of the property |
112 |
* @exception IllegalArgumentException if name string contains an |
* @param actions the action string |
113 |
* illegal wildcard or actions string contains an illegal action |
* @throws IllegalArgumentException if name string contains an |
114 |
|
* illegal wildcard or actions string contains an illegal action |
115 |
*/ |
*/ |
116 |
public PropertyPermission(String name, String actions) |
public PropertyPermission(String name, String actions) |
117 |
{ |
{ |
122 |
/** |
/** |
123 |
* Parse the action string and convert actions from external to internal |
* Parse the action string and convert actions from external to internal |
124 |
* form. This will set the internal actions field. |
* form. This will set the internal actions field. |
125 |
* @param actions the action string. |
* |
126 |
* @exception IllegalArgumentException if actions string contains an |
* @param actions the action string |
127 |
* illegal action */ |
* @throws IllegalArgumentException if actions string contains an |
128 |
|
* illegal action |
129 |
|
*/ |
130 |
private void setActions(String actions) |
private void setActions(String actions) |
131 |
{ |
{ |
132 |
this.actions = 0; |
this.actions = 0; |
133 |
StringTokenizer actionTokenizer = new StringTokenizer(actions, ","); |
StringTokenizer actionTokenizer = new StringTokenizer(actions, ","); |
134 |
while (actionTokenizer.hasMoreElements()) |
while (actionTokenizer.hasMoreElements()) |
135 |
{ |
{ |
136 |
String anAction = actionTokenizer.nextToken(); |
String anAction = actionTokenizer.nextToken(); |
137 |
if ("read".equals(anAction)) |
if ("read".equals(anAction)) |
138 |
this.actions |= READ; |
this.actions |= READ; |
139 |
else if ("write".equals(anAction)) |
else if ("write".equals(anAction)) |
140 |
this.actions |= WRITE; |
this.actions |= WRITE; |
141 |
else |
else |
142 |
throw new IllegalArgumentException("illegal action " + anAction); |
throw new IllegalArgumentException("illegal action " + anAction); |
143 |
} |
} |
144 |
} |
} |
145 |
|
|
146 |
/** |
/** |
147 |
|
* Reads an object from the stream. This converts the external to the |
148 |
|
* internal representation. |
149 |
|
* |
150 |
|
* @param s the stream to read from |
151 |
|
* @throws IOException if the stream fails |
152 |
|
* @throws ClassNotFoundException if reserialization fails |
153 |
|
*/ |
154 |
|
private void readObject(ObjectInputStream s) |
155 |
|
throws IOException, ClassNotFoundException |
156 |
|
{ |
157 |
|
ObjectInputStream.GetField fields = s.readFields(); |
158 |
|
setActions((String) fields.get("actions", null)); |
159 |
|
} |
160 |
|
|
161 |
|
/** |
162 |
|
* Writes an object to the stream. This converts the internal to the |
163 |
|
* external representation. |
164 |
|
* |
165 |
|
* @param s the stram to write to |
166 |
|
* @throws IOException if the stream fails |
167 |
|
*/ |
168 |
|
private void writeObject(ObjectOutputStream s) throws IOException |
169 |
|
{ |
170 |
|
ObjectOutputStream.PutField fields = s.putFields(); |
171 |
|
fields.put("actions", getActions()); |
172 |
|
s.writeFields(); |
173 |
|
} |
174 |
|
|
175 |
|
/** |
176 |
* Check if this permission implies p. This returns true iff all of |
* Check if this permission implies p. This returns true iff all of |
177 |
* the following conditions are true: |
* the following conditions are true: |
178 |
* <ul> |
* <ul> |
179 |
* <li> p is a PropertyPermission </li> |
* <li> p is a PropertyPermission </li> |
180 |
* <li> this.getName() implies p.getName(), |
* <li> this.getName() implies p.getName(), |
181 |
* e.g. <code>java.*</code> implies <code>java.home</code> </li> |
* e.g. <code>java.*</code> implies <code>java.home</code> </li> |
182 |
* <li> this.getActions is a subset of p.getActions </li> |
* <li> this.getActions is a subset of p.getActions </li> |
183 |
* </ul> |
* </ul> |
184 |
|
* |
185 |
|
* @param p the permission to check |
186 |
|
* @return true if this permission implies p |
187 |
*/ |
*/ |
188 |
public boolean implies(Permission p) |
public boolean implies(Permission p) |
189 |
{ |
{ |
190 |
if (!(p instanceof PropertyPermission)) |
if (! (p instanceof PropertyPermission)) |
191 |
return false; |
return false; |
192 |
|
|
193 |
// We have to check the actions. |
// We have to check the actions. |
196 |
return false; |
return false; |
197 |
|
|
198 |
// BasicPermission checks for name. |
// BasicPermission checks for name. |
199 |
if (!super.implies(p)) |
return (!super.implies(p)) |
200 |
return false; |
return false; |
201 |
|
|
202 |
return true; |
return true; |
203 |
} |
} |
204 |
|
|
205 |
/** |
/** |
|
* Returns the action string. Note that this may differ from the string |
|
|
* given at the constructor: The actions are converted to lowercase and |
|
|
* may be reordered. |
|
|
*/ |
|
|
public String getActions() |
|
|
{ |
|
|
return actionStrings[actions]; |
|
|
} |
|
|
|
|
|
/** |
|
206 |
* Check to see whether this object is the same as another |
* Check to see whether this object is the same as another |
207 |
* PropertyPermission object. |
* PropertyPermission object; this is true if it has the same name and |
208 |
|
* actions. |
209 |
* |
* |
210 |
* @param obj The other object |
* @param obj the other object |
211 |
|
* @return true if the two are equivalent |
212 |
*/ |
*/ |
213 |
public boolean equals (Object obj) |
public boolean equals(Object obj) |
214 |
{ |
{ |
215 |
if (! (obj instanceof PropertyPermission)) |
if (! (obj instanceof PropertyPermission)) |
216 |
return false; |
return false; |
217 |
PropertyPermission p = (PropertyPermission) obj; |
PropertyPermission p = (PropertyPermission) obj; |
218 |
return actions == p.actions && super.equals (p); |
return actions == p.actions && super.equals(p); |
219 |
} |
} |
220 |
|
|
221 |
/** |
/** |
222 |
* Reads an object from the stream. This converts the external to the |
* Returns the hash code for this permission. It is equivalent to |
223 |
* internal representation. |
* <code>getName().hashCode()</code>. |
224 |
|
* |
225 |
|
* @return the hash code |
226 |
|
* @XXX Add this method. |
227 |
*/ |
*/ |
228 |
private void readObject(ObjectInputStream s) |
|
|
throws IOException, ClassNotFoundException |
|
|
{ |
|
|
ObjectInputStream.GetField fields = s.readFields(); |
|
|
setActions((String) fields.get("actions", null)); |
|
|
} |
|
229 |
|
|
230 |
/** |
/** |
231 |
* Writes an object to the stream. This converts the internal to the |
* Returns the action string. Note that this may differ from the string |
232 |
* external representation. |
* given at the constructor: The actions are converted to lowercase and |
233 |
|
* may be reordered. |
234 |
|
* |
235 |
|
* @return one of "", "read", "write", or "read,write" |
236 |
*/ |
*/ |
237 |
private void writeObject(ObjectOutputStream s) throws IOException |
public String getActions() |
238 |
{ |
{ |
239 |
ObjectOutputStream.PutField fields = s.putFields(); |
return actionStrings[actions]; |
|
fields.put("actions", getActions()); |
|
|
s.writeFields(); |
|
240 |
} |
} |
241 |
|
|
242 |
/** |
/** |
243 |
* Returns a permission collection suitable to take |
* Returns a permission collection suitable to take |
244 |
* PropertyPermission objects. |
* PropertyPermission objects. |
245 |
* @return a new empty PermissionCollection. |
* |
246 |
|
* @return a new empty PermissionCollection |
247 |
|
* @XXX JDK uses a default class, java.util.PropertyPermissionCollection, |
248 |
|
* instead of an anonymous class. |
249 |
*/ |
*/ |
250 |
public PermissionCollection newPermissionCollection() |
public PermissionCollection newPermissionCollection() |
251 |
{ |
{ |
256 |
|
|
257 |
public void add(Permission permission) |
public void add(Permission permission) |
258 |
{ |
{ |
259 |
if (isReadOnly()) |
if (isReadOnly()) |
260 |
throw new IllegalStateException("readonly"); |
throw new IllegalStateException("readonly"); |
261 |
|
|
262 |
// also check that permission is of correct type. |
// also check that permission is of correct type. |
263 |
PropertyPermission pp = (PropertyPermission) permission; |
PropertyPermission pp = (PropertyPermission) permission; |
264 |
String name = pp.getName(); |
String name = pp.getName(); |
265 |
if (name.equals("*")) |
if (name.equals("*")) |
266 |
allActions |= pp.actions; |
allActions |= pp.actions; |
267 |
permissions.put(name, pp); |
permissions.put(name, pp); |
268 |
} |
} |
269 |
|
|
270 |
public boolean implies(Permission permission) |
public boolean implies(Permission permission) |
271 |
{ |
{ |
272 |
if (!(permission instanceof PropertyPermission)) |
if (!(permission instanceof PropertyPermission)) |
273 |
return false; |
return false; |
274 |
|
|
275 |
PropertyPermission toImply = (PropertyPermission) permission; |
PropertyPermission toImply = (PropertyPermission) permission; |
276 |
if ((toImply.actions & ~allActions) == 0) |
if ((toImply.actions & ~allActions) == 0) |
277 |
return true; |
return true; |
278 |
|
|
279 |
String name = toImply.getName(); |
String name = toImply.getName(); |
280 |
if (name.equals("*")) |
if (name.equals("*")) |
281 |
return false; |
return false; |
282 |
|
|
283 |
int prefixLength = name.length(); |
int prefixLength = name.length(); |
284 |
if (name.endsWith("*")) |
if (name.endsWith("*")) |
285 |
prefixLength -= 2; |
prefixLength -= 2; |
286 |
|
|
287 |
while (true) |
while (true) |
288 |
{ |
{ |
289 |
PropertyPermission forName = |
PropertyPermission forName = |
290 |
(PropertyPermission) permissions.get(name); |
(PropertyPermission) permissions.get(name); |
291 |
if (forName != null && (toImply.actions & ~forName.actions) == 0) |
if (forName != null && (toImply.actions & ~forName.actions) == 0) |
292 |
return true; |
return true; |
293 |
|
|
294 |
prefixLength = name.lastIndexOf('.', prefixLength); |
prefixLength = name.lastIndexOf('.', prefixLength); |
295 |
if (prefixLength < 0) |
if (prefixLength < 0) |
296 |
return false; |
return false; |
297 |
name = name.substring(0, prefixLength + 1) + '*'; |
name = name.substring(0, prefixLength + 1) + '*'; |
298 |
} |
} |
299 |
} |
} |
300 |
|
|
301 |
public Enumeration elements() |
public Enumeration elements() |
302 |
{ |
{ |
303 |
return permissions.elements(); |
return permissions.elements(); |
304 |
} |
} |
305 |
}; |
}; |
306 |
} |
} |