1 /* |
1 /* |
2 * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
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 |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. Oracle designates this |
7 * published by the Free Software Foundation. Oracle designates this |
23 * questions. |
23 * questions. |
24 */ |
24 */ |
25 |
25 |
26 package javax.security.auth.kerberos; |
26 package javax.security.auth.kerberos; |
27 |
27 |
|
28 import java.io.IOException; |
|
29 import java.io.ObjectInputStream; |
|
30 import java.io.ObjectOutputStream; |
|
31 import java.io.ObjectStreamField; |
|
32 import java.security.BasicPermission; |
|
33 import java.security.Permission; |
|
34 import java.security.PermissionCollection; |
28 import java.util.*; |
35 import java.util.*; |
29 import java.security.Permission; |
36 import java.util.concurrent.ConcurrentHashMap; |
30 import java.security.BasicPermission; |
|
31 import java.security.PermissionCollection; |
|
32 import java.io.ObjectStreamField; |
|
33 import java.io.ObjectOutputStream; |
|
34 import java.io.ObjectInputStream; |
|
35 import java.io.IOException; |
|
36 |
37 |
37 /** |
38 /** |
38 * This class is used to restrict the usage of the Kerberos |
39 * This class is used to restrict the usage of the Kerberos |
39 * delegation model, ie: forwardable and proxiable tickets. |
40 * delegation model, ie: forwardable and proxiable tickets. |
40 * <p> |
41 * <p> |
135 * @param p the permission to check against. |
136 * @param p the permission to check against. |
136 * |
137 * |
137 * @return true if the specified permission is implied by this object, |
138 * @return true if the specified permission is implied by this object, |
138 * false if not. |
139 * false if not. |
139 */ |
140 */ |
|
141 @Override |
140 public boolean implies(Permission p) { |
142 public boolean implies(Permission p) { |
141 if (!(p instanceof DelegationPermission)) |
143 if (!(p instanceof DelegationPermission)) |
142 return false; |
144 return false; |
143 |
145 |
144 DelegationPermission that = (DelegationPermission) p; |
146 DelegationPermission that = (DelegationPermission) p; |
157 * |
159 * |
158 * @return true if {@code obj} is a DelegationPermission, and |
160 * @return true if {@code obj} is a DelegationPermission, and |
159 * has the same subordinate and service principal as this. |
161 * has the same subordinate and service principal as this. |
160 * DelegationPermission object. |
162 * DelegationPermission object. |
161 */ |
163 */ |
|
164 @Override |
162 public boolean equals(Object obj) { |
165 public boolean equals(Object obj) { |
163 if (obj == this) |
166 if (obj == this) |
164 return true; |
167 return true; |
165 |
168 |
166 if (! (obj instanceof DelegationPermission)) |
169 if (! (obj instanceof DelegationPermission)) |
173 /** |
176 /** |
174 * Returns the hash code value for this object. |
177 * Returns the hash code value for this object. |
175 * |
178 * |
176 * @return a hash code value for this object. |
179 * @return a hash code value for this object. |
177 */ |
180 */ |
|
181 @Override |
178 public int hashCode() { |
182 public int hashCode() { |
179 return getName().hashCode(); |
183 return getName().hashCode(); |
180 } |
184 } |
181 |
|
182 |
185 |
183 /** |
186 /** |
184 * Returns a PermissionCollection object for storing |
187 * Returns a PermissionCollection object for storing |
185 * DelegationPermission objects. |
188 * DelegationPermission objects. |
186 * <br> |
189 * <br> |
190 * be implemented in an efficient (and consistent) manner. |
193 * be implemented in an efficient (and consistent) manner. |
191 * |
194 * |
192 * @return a new PermissionCollection object suitable for storing |
195 * @return a new PermissionCollection object suitable for storing |
193 * DelegationPermissions. |
196 * DelegationPermissions. |
194 */ |
197 */ |
195 |
198 @Override |
196 public PermissionCollection newPermissionCollection() { |
199 public PermissionCollection newPermissionCollection() { |
197 return new KrbDelegationPermissionCollection(); |
200 return new KrbDelegationPermissionCollection(); |
198 } |
201 } |
199 |
202 |
200 /** |
203 /** |
261 |
264 |
262 final class KrbDelegationPermissionCollection extends PermissionCollection |
265 final class KrbDelegationPermissionCollection extends PermissionCollection |
263 implements java.io.Serializable { |
266 implements java.io.Serializable { |
264 |
267 |
265 // Not serialized; see serialization section at end of class. |
268 // Not serialized; see serialization section at end of class. |
266 private transient List<Permission> perms; |
269 private transient ConcurrentHashMap<Permission, Boolean> perms; |
267 |
270 |
268 public KrbDelegationPermissionCollection() { |
271 public KrbDelegationPermissionCollection() { |
269 perms = new ArrayList<Permission>(); |
272 perms = new ConcurrentHashMap<>(); |
270 } |
273 } |
271 |
|
272 |
274 |
273 /** |
275 /** |
274 * Check and see if this collection of permissions implies the permissions |
276 * Check and see if this collection of permissions implies the permissions |
275 * expressed in "permission". |
277 * expressed in "permission". |
276 * |
278 * |
277 * @param permission the Permission object to compare |
279 * @param permission the Permission object to compare |
278 * |
280 * |
279 * @return true if "permission" is a proper subset of a permission in |
281 * @return true if "permission" is a proper subset of a permission in |
280 * the collection, false if not. |
282 * the collection, false if not. |
281 */ |
283 */ |
|
284 @Override |
282 public boolean implies(Permission permission) { |
285 public boolean implies(Permission permission) { |
283 if (! (permission instanceof DelegationPermission)) |
286 if (! (permission instanceof DelegationPermission)) |
284 return false; |
287 return false; |
285 |
288 |
286 synchronized (this) { |
289 // if map contains key, then it automatically implies it |
287 for (Permission x : perms) { |
290 return perms.containsKey(permission); |
288 if (x.implies(permission)) |
|
289 return true; |
|
290 } |
|
291 } |
|
292 return false; |
|
293 |
|
294 } |
291 } |
295 |
292 |
296 /** |
293 /** |
297 * Adds a permission to the DelegationPermissions. The key for |
294 * Adds a permission to the DelegationPermissions. The key for |
298 * the hash is the name. |
295 * the hash is the name. |
303 * DelegationPermission |
300 * DelegationPermission |
304 * |
301 * |
305 * @exception SecurityException - if this PermissionCollection object |
302 * @exception SecurityException - if this PermissionCollection object |
306 * has been marked readonly |
303 * has been marked readonly |
307 */ |
304 */ |
|
305 @Override |
308 public void add(Permission permission) { |
306 public void add(Permission permission) { |
309 if (! (permission instanceof DelegationPermission)) |
307 if (! (permission instanceof DelegationPermission)) |
310 throw new IllegalArgumentException("invalid permission: "+ |
308 throw new IllegalArgumentException("invalid permission: "+ |
311 permission); |
309 permission); |
312 if (isReadOnly()) |
310 if (isReadOnly()) |
313 throw new SecurityException("attempt to add a Permission to a readonly PermissionCollection"); |
311 throw new SecurityException("attempt to add a Permission to a readonly PermissionCollection"); |
314 |
312 |
315 synchronized (this) { |
313 perms.put(permission, Boolean.TRUE); |
316 perms.add(0, permission); |
|
317 } |
|
318 } |
314 } |
319 |
315 |
320 /** |
316 /** |
321 * Returns an enumeration of all the DelegationPermission objects |
317 * Returns an enumeration of all the DelegationPermission objects |
322 * in the container. |
318 * in the container. |
323 * |
319 * |
324 * @return an enumeration of all the DelegationPermission objects. |
320 * @return an enumeration of all the DelegationPermission objects. |
325 */ |
321 */ |
|
322 @Override |
326 public Enumeration<Permission> elements() { |
323 public Enumeration<Permission> elements() { |
327 // Convert Iterator into Enumeration |
324 return perms.keys(); |
328 synchronized (this) { |
|
329 return Collections.enumeration(perms); |
|
330 } |
|
331 } |
325 } |
332 |
326 |
333 private static final long serialVersionUID = -3383936936589966948L; |
327 private static final long serialVersionUID = -3383936936589966948L; |
334 |
328 |
335 // Need to maintain serialization interoperability with earlier releases, |
329 // Need to maintain serialization interoperability with earlier releases, |
352 */ |
346 */ |
353 private void writeObject(ObjectOutputStream out) throws IOException { |
347 private void writeObject(ObjectOutputStream out) throws IOException { |
354 // Don't call out.defaultWriteObject() |
348 // Don't call out.defaultWriteObject() |
355 |
349 |
356 // Write out Vector |
350 // Write out Vector |
357 Vector<Permission> permissions = new Vector<>(perms.size()); |
351 Vector<Permission> permissions = new Vector<>(perms.keySet()); |
358 |
|
359 synchronized (this) { |
|
360 permissions.addAll(perms); |
|
361 } |
|
362 |
352 |
363 ObjectOutputStream.PutField pfields = out.putFields(); |
353 ObjectOutputStream.PutField pfields = out.putFields(); |
364 pfields.put("permissions", permissions); |
354 pfields.put("permissions", permissions); |
365 out.writeFields(); |
355 out.writeFields(); |
366 } |
356 } |
377 // Read in serialized fields |
367 // Read in serialized fields |
378 ObjectInputStream.GetField gfields = in.readFields(); |
368 ObjectInputStream.GetField gfields = in.readFields(); |
379 |
369 |
380 // Get the one we want |
370 // Get the one we want |
381 Vector<Permission> permissions = |
371 Vector<Permission> permissions = |
382 (Vector<Permission>)gfields.get("permissions", null); |
372 (Vector<Permission>)gfields.get("permissions", null); |
383 perms = new ArrayList<Permission>(permissions.size()); |
373 perms = new ConcurrentHashMap<>(permissions.size()); |
384 perms.addAll(permissions); |
374 for (Permission perm : permissions) { |
|
375 perms.put(perm, Boolean.TRUE); |
|
376 } |
385 } |
377 } |
386 } |
378 } |