]>
Commit | Line | Data |
---|---|---|
6f5ce93b AT |
1 | /* PrivateCredentialPermission.java -- permissions governing private credentials. |
2 | Copyright (C) 2004 Free Software Foundation, Inc. | |
3 | ||
4 | This file is part of GNU Classpath. | |
5 | ||
6 | GNU Classpath is free software; you can redistribute it and/or modify | |
7 | it under the terms of the GNU General Public License as published by | |
8 | the Free Software Foundation; either version 2, or (at your option) | |
9 | any later version. | |
10 | ||
11 | GNU Classpath is distributed in the hope that it will be useful, but | |
12 | WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 | General Public License for more details. | |
15 | ||
16 | You should have received a copy of the GNU General Public License | |
17 | along with GNU Classpath; see the file COPYING. If not, write to the | |
18 | Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | |
19 | 02111-1307 USA. | |
20 | ||
21 | Linking this library statically or dynamically with other modules is | |
22 | making a combined work based on this library. Thus, the terms and | |
23 | conditions of the GNU General Public License cover the whole | |
24 | combination. | |
25 | ||
26 | As a special exception, the copyright holders of this library give you | |
27 | permission to link this library with independent modules to produce an | |
28 | executable, regardless of the license terms of these independent | |
29 | modules, and to copy and distribute the resulting executable under | |
30 | terms of your choice, provided that you also meet, for each linked | |
31 | independent module, the terms and conditions of the license of that | |
32 | module. An independent module is a module which is not derived from | |
33 | or based on this library. If you modify this library, you may extend | |
34 | this exception to your version of the library, but you are not | |
35 | obligated to do so. If you do not wish to do so, delete this | |
36 | exception statement from your version. */ | |
37 | ||
38 | ||
39 | package javax.security.auth; | |
40 | ||
41 | import java.io.Serializable; | |
42 | ||
43 | import java.security.Permission; | |
44 | import java.security.PermissionCollection; | |
45 | ||
46 | import java.util.HashSet; | |
47 | import java.util.Iterator; | |
48 | import java.util.Set; | |
49 | import java.util.StringTokenizer; | |
50 | ||
51 | /** | |
52 | * A permission governing access to a private credential. The action of this | |
53 | * permission is always "read" -- meaning that the private credential | |
54 | * information can be read from an object. | |
55 | * | |
56 | * <p>The target of this permission is formatted as follows:</p> | |
57 | * | |
58 | * <p><code>CredentialClassName ( PrinicpalClassName PrincipalName )*</code></p> | |
59 | * | |
60 | * <p><i>CredentialClassName</i> is either the name of a private credential | |
61 | * class name, or a wildcard character (<code>'*'</code>). | |
62 | * <i>PrinicpalClassName</i> is the class name of a principal object, and | |
63 | * <i>PrincipalName</i> is a string representing the principal, or the | |
64 | * wildcard character.</p> | |
65 | */ | |
a7349816 | 66 | public final class PrivateCredentialPermission extends Permission |
6f5ce93b AT |
67 | implements Serializable |
68 | { | |
7e53ab66 AJH |
69 | /** |
70 | * For compatability with Sun's JDK 1.4.2 rev. 5 | |
71 | */ | |
72 | private static final long serialVersionUID = 5284372143517237068L; | |
6f5ce93b AT |
73 | |
74 | // Fields. | |
75 | // ------------------------------------------------------------------------- | |
76 | ||
77 | /** | |
78 | * @serial The credential class name. | |
79 | */ | |
80 | private final String credentialClass; | |
81 | ||
82 | /** | |
83 | * @serial The principals, a set of CredOwner objects (an undocumented | |
84 | * inner class of this class). | |
85 | */ | |
86 | private final Set principals; | |
87 | ||
88 | /** | |
89 | * @serial Who knows? | |
90 | */ | |
91 | private final boolean testing; | |
92 | ||
93 | // Constructor. | |
94 | // ------------------------------------------------------------------------- | |
95 | ||
96 | /** | |
97 | * Create a new private credential permission. | |
98 | * | |
99 | * @param name The permission target name. | |
100 | * @param actions The list of actions, which, for this class, must be | |
101 | * <code>"read"</code>. | |
102 | */ | |
103 | public PrivateCredentialPermission (final String name, String actions) | |
104 | { | |
105 | super(name); | |
106 | actions = actions.trim().toLowerCase(); | |
107 | if (!"read".equals (actions)) | |
108 | { | |
109 | throw new IllegalArgumentException("actions must be \"read\""); | |
110 | } | |
111 | StringTokenizer st = new StringTokenizer (name, " \"'"); | |
112 | principals = new HashSet(); | |
113 | if (st.countTokens() < 3 || (st.countTokens() & 1) == 0) | |
114 | { | |
115 | throw new IllegalArgumentException ("badly formed credential name"); | |
116 | } | |
117 | credentialClass = st.nextToken(); | |
118 | while (st.hasMoreTokens()) | |
119 | { | |
120 | principals.add (new CredOwner (st.nextToken(), st.nextToken())); | |
121 | } | |
122 | testing = false; // WTF ever. | |
123 | } | |
124 | ||
125 | // Instance methods. | |
126 | // ------------------------------------------------------------------------- | |
127 | ||
128 | public boolean equals (Object o) | |
129 | { | |
130 | if (! (o instanceof PrivateCredentialPermission)) | |
131 | { | |
132 | return false; | |
133 | } | |
134 | PrivateCredentialPermission that = (PrivateCredentialPermission) o; | |
135 | if (!that.getActions().equals (getActions())) | |
136 | { | |
137 | return false; | |
138 | } | |
139 | if (!that.getCredentialClass().equals (getCredentialClass())) | |
140 | { | |
141 | return false; | |
142 | } | |
143 | ||
144 | final String[][] principals = getPrincipals(); | |
145 | final String[][] that_principals = that.getPrincipals(); | |
146 | if (that_principals == null) | |
147 | { | |
148 | return false; | |
149 | } | |
150 | if (that_principals.length != principals.length) | |
151 | { | |
152 | return false; | |
153 | } | |
154 | for (int i = 0; i < principals.length; i++) | |
155 | { | |
156 | if (!principals[i][0].equals (that_principals[i][0]) || | |
157 | !principals[i][1].equals (that_principals[i][1])) | |
158 | { | |
159 | return false; | |
160 | } | |
161 | } | |
162 | return true; | |
163 | } | |
164 | ||
165 | /** | |
166 | * Returns the actions this permission encompasses. For private credential | |
167 | * permissions, this is always the string <code>"read"</code>. | |
168 | * | |
169 | * @return The list of actions. | |
170 | */ | |
171 | public String getActions() | |
172 | { | |
173 | return "read"; | |
174 | } | |
175 | ||
176 | /** | |
177 | * Returns the credential class name that was embedded in this permission's | |
178 | * target name. | |
179 | * | |
180 | * @return The credential class name. | |
181 | */ | |
182 | public String getCredentialClass() | |
183 | { | |
184 | return credentialClass; | |
185 | } | |
186 | ||
187 | /** | |
188 | * Returns the principal list that was embedded in this permission's target | |
189 | * name. | |
190 | * | |
191 | * <p>Each element of the returned array is a pair; the first element is the | |
192 | * principal class name, and the second is the principal name. | |
193 | * | |
194 | * @return The principal list. | |
195 | */ | |
196 | public String[][] getPrincipals() | |
197 | { | |
198 | String[][] ret = new String[principals.size()][]; | |
199 | Iterator it = principals.iterator(); | |
200 | for (int i = 0; i < principals.size() && it.hasNext(); i++) | |
201 | { | |
202 | CredOwner co = (CredOwner) it.next(); | |
203 | ret[i] = new String[] { co.getPrincipalClass(), co.getPrincipalName() }; | |
204 | } | |
205 | return ret; | |
206 | } | |
207 | ||
208 | public int hashCode() | |
209 | { | |
210 | return credentialClass.hashCode() + principals.hashCode(); | |
211 | } | |
212 | ||
213 | /** | |
214 | * Test if this permission implies another. This method returns true if: | |
215 | * | |
216 | * <ol> | |
217 | * <li><i>p</i> is an instance of PrivateCredentialPermission</li>. | |
218 | * <li>The credential class name of this instance matches that of <i>p</i>, | |
219 | * and one of the principals of <i>p</i> is contained in the principals of | |
220 | * this class. Thus, | |
221 | * <ul> | |
222 | * <li><code>[ * P "foo" ] implies [ C P "foo" ]</code></li> | |
223 | * <li><code>[ C P1 "foo" ] implies [ C P1 "foo" P2 "bar" ]</code></li> | |
224 | * <li><code>[ C P1 "*" ] implies [ C P1 "foo" ]</code></li> | |
225 | * </ul> | |
226 | * </ol> | |
227 | * | |
228 | * @param p The permission to check. | |
229 | * @return True if this permission implies <i>p</i>. | |
230 | */ | |
231 | public boolean implies (Permission p) | |
232 | { | |
233 | if (! (p instanceof PrivateCredentialPermission)) | |
234 | { | |
235 | return false; | |
236 | } | |
237 | PrivateCredentialPermission that = (PrivateCredentialPermission) p; | |
238 | if (!credentialClass.equals ("*") | |
239 | && !credentialClass.equals (that.getCredentialClass())) | |
240 | { | |
241 | return false; | |
242 | } | |
243 | String[][] principals = getPrincipals(); | |
244 | String[][] that_principals = that.getPrincipals(); | |
245 | if (that_principals == null) | |
246 | { | |
247 | return false; | |
248 | } | |
249 | for (int i = 0; i < principals.length; i++) | |
250 | { | |
251 | for (int j = 0; j < that_principals.length; j++) | |
252 | { | |
253 | if (principals[i][0].equals (that_principals[j][0]) && | |
254 | (principals[i][1].equals ("*") || | |
255 | principals[i][1].equals (that_principals[j][1]))) | |
256 | { | |
257 | return true; | |
258 | } | |
259 | } | |
260 | } | |
261 | return false; | |
262 | } | |
263 | ||
264 | /** | |
265 | * This method is not necessary for this class, thus it always returns null. | |
266 | * | |
267 | * @return null. | |
268 | */ | |
269 | public PermissionCollection newPermissionCollection() | |
270 | { | |
271 | return null; | |
272 | } | |
273 | ||
274 | // Inner class. | |
275 | // ------------------------------------------------------------------------- | |
276 | ||
277 | /** | |
278 | * An undocumented inner class present for serialization compatibility. | |
279 | */ | |
280 | private static class CredOwner implements Serializable | |
281 | { | |
282 | ||
283 | // Fields. | |
284 | // ----------------------------------------------------------------------- | |
285 | ||
286 | private final String principalClass; | |
287 | private final String principalName; | |
288 | ||
289 | // Constructor. | |
290 | // ----------------------------------------------------------------------- | |
291 | ||
292 | CredOwner (final String principalClass, final String principalName) | |
293 | { | |
294 | this.principalClass = principalClass; | |
295 | this.principalName = principalName; | |
296 | } | |
297 | ||
298 | // Instance methods. | |
299 | // ----------------------------------------------------------------------- | |
300 | ||
301 | public boolean equals (Object o) | |
302 | { | |
303 | if (!(o instanceof CredOwner)) | |
304 | { | |
305 | return false; | |
306 | } | |
307 | return principalClass.equals (((CredOwner) o).getPrincipalClass()) && | |
308 | principalName.equals (((CredOwner) o).getPrincipalName()); | |
309 | } | |
310 | ||
311 | public int hashCode() | |
312 | { | |
313 | return principalClass.hashCode() + principalName.hashCode(); | |
314 | } | |
315 | ||
316 | public String getPrincipalClass() | |
317 | { | |
318 | return principalClass; | |
319 | } | |
320 | ||
321 | public String getPrincipalName() | |
322 | { | |
323 | return principalName; | |
324 | } | |
325 | } | |
326 | } |