| /* |
| * $Header: /cvshome/build/info.dmtree/src/info/dmtree/security/DmtPrincipalPermission.java,v 1.4 2006/07/12 21:21:52 hargrave Exp $ |
| * |
| * Copyright (c) OSGi Alliance (2004, 2006). All Rights Reserved. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package info.dmtree.security; |
| |
| import java.security.Permission; |
| import java.security.PermissionCollection; |
| import java.util.*; |
| |
| /** |
| * Indicates the callers authority to create DMT sessions on behalf of a remote |
| * management server. Only protocol adapters communicating with management |
| * servers should be granted this permission. |
| * <p> |
| * <code>DmtPrincipalPermission</code> has a target string which controls the |
| * name of the principal on whose behalf the protocol adapter can act. A |
| * wildcard is allowed at the end of the target string, to allow using any |
| * principal name with the given prefix. The "*" target means the |
| * adapter can create a session in the name of any principal. |
| */ |
| public class DmtPrincipalPermission extends Permission { |
| private static final long serialVersionUID = 6388752177325038332L; |
| |
| // specifies whether the target string had a wildcard at the end |
| private final boolean isPrefix; |
| |
| // the target string without the wildcard (if there was one) |
| private final String principal; |
| |
| /** |
| * Creates a new <code>DmtPrincipalPermission</code> object with its name |
| * set to the target string. Name must be non-null and non-empty. |
| * |
| * @param target the name of the principal, can end with <code>*</code> to |
| * match any principal with the given prefix |
| * @throws NullPointerException if <code>name</code> is <code>null</code> |
| * @throws IllegalArgumentException if <code>name</code> is empty |
| */ |
| public DmtPrincipalPermission(String target) { |
| super(target); |
| |
| if (target == null) |
| throw new NullPointerException( |
| "'target' parameter must not be null."); |
| |
| if (target.equals("")) |
| throw new IllegalArgumentException( |
| "'target' parameter must not be empty."); |
| |
| isPrefix = target.endsWith("*"); |
| if (isPrefix) |
| principal = target.substring(0, target.length() - 1); |
| else |
| principal = target; |
| } |
| |
| /** |
| * Creates a new <code>DmtPrincipalPermission</code> object using the |
| * 'canonical' two argument constructor. In this version this class does not |
| * define any actions, the second argument of this constructor must be "*" |
| * so that this class can later be extended in a backward compatible way. |
| * |
| * @param target the name of the principal, can end with <code>*</code> to |
| * match any principal with the given prefix |
| * @param actions no actions defined, must be "*" for forward compatibility |
| * @throws NullPointerException if <code>name</code> or |
| * <code>actions</code> is <code>null</code> |
| * @throws IllegalArgumentException if <code>name</code> is empty or |
| * <code>actions</code> is not "*" |
| */ |
| public DmtPrincipalPermission(String target, String actions) { |
| this(target); |
| |
| if (actions == null) |
| throw new NullPointerException( |
| "'actions' parameter must not be null."); |
| |
| if (!actions.equals("*")) |
| throw new IllegalArgumentException( |
| "'actions' parameter must be \"*\"."); |
| } |
| |
| /** |
| * Checks whether the given object is equal to this DmtPrincipalPermission |
| * instance. Two DmtPrincipalPermission instances are equal if they have the |
| * same target string. |
| * |
| * @param obj the object to compare to this DmtPrincipalPermission instance |
| * @return <code>true</code> if the parameter represents the same |
| * permissions as this instance |
| */ |
| public boolean equals(Object obj) { |
| if (obj == this) |
| return true; |
| |
| if (!(obj instanceof DmtPrincipalPermission)) |
| return false; |
| |
| DmtPrincipalPermission other = (DmtPrincipalPermission) obj; |
| |
| return isPrefix == other.isPrefix && principal.equals(other.principal); |
| } |
| |
| /** |
| * Returns the action list (always <code>*</code> in the current version). |
| * |
| * @return the action string "*" |
| */ |
| public String getActions() { |
| return "*"; |
| } |
| |
| /** |
| * Returns the hash code for this permission object. If two |
| * DmtPrincipalPermission objects are equal according to the {@link #equals} |
| * method, then calling this method on each of the two |
| * DmtPrincipalPermission objects must produce the same integer result. |
| * |
| * @return hash code for this permission object |
| */ |
| public int hashCode() { |
| return new Boolean(isPrefix).hashCode() ^ principal.hashCode(); |
| } |
| |
| /** |
| * Checks if this DmtPrincipalPermission object implies the specified |
| * permission. Another DmtPrincipalPermission instance is implied by this |
| * permission either if the target strings are identical, or if this target |
| * can be made identical to the other target by replacing a trailing |
| * "*" with any string. |
| * |
| * @param p the permission to check for implication |
| * @return true if this DmtPrincipalPermission instance implies the |
| * specified permission |
| */ |
| public boolean implies(Permission p) { |
| if (!(p instanceof DmtPrincipalPermission)) |
| return false; |
| |
| DmtPrincipalPermission other = (DmtPrincipalPermission) p; |
| |
| return impliesPrincipal(other); |
| } |
| |
| /** |
| * Returns a new PermissionCollection object for storing |
| * DmtPrincipalPermission objects. |
| * |
| * @return the new PermissionCollection |
| */ |
| public PermissionCollection newPermissionCollection() { |
| return new DmtPrincipalPermissionCollection(); |
| } |
| |
| /* |
| * Returns true if the principal parameter of the given |
| * DmtPrincipalPermission is implied by the principal of this permission, |
| * i.e. this principal is a prefix of the other principal but ends with a *, |
| * or the two principal strings are equal. |
| */ |
| boolean impliesPrincipal(DmtPrincipalPermission p) { |
| return isPrefix ? p.principal.startsWith(principal) : !p.isPrefix |
| && p.principal.equals(principal); |
| } |
| } |
| |
| /** |
| * Represents a homogeneous collection of DmtPrincipalPermission objects. |
| */ |
| final class DmtPrincipalPermissionCollection extends PermissionCollection { |
| private static final long serialVersionUID = -6692103535775802684L; |
| |
| private ArrayList perms; |
| |
| /** |
| * Create an empty DmtPrincipalPermissionCollection object. |
| */ |
| public DmtPrincipalPermissionCollection() { |
| perms = new ArrayList(); |
| } |
| |
| /** |
| * Adds a permission to the DmtPrincipalPermissionCollection. |
| * |
| * @param permission the Permission object to add |
| * @exception IllegalArgumentException if the permission is not a |
| * DmtPrincipalPermission |
| * @exception SecurityException if this DmtPrincipalPermissionCollection |
| * object has been marked readonly |
| */ |
| public void add(Permission permission) { |
| if (!(permission instanceof DmtPrincipalPermission)) |
| throw new IllegalArgumentException( |
| "Cannot add permission, invalid permission type: " |
| + permission); |
| if (isReadOnly()) |
| throw new SecurityException( |
| "Cannot add permission, collection is marked read-only."); |
| |
| // only add new permission if it is not already implied by the |
| // permissions in the collection |
| if (!implies(permission)) { |
| // remove all permissions that are implied by the new one |
| Iterator i = perms.iterator(); |
| while (i.hasNext()) |
| if (permission.implies((DmtPrincipalPermission) i.next())) |
| i.remove(); |
| |
| // no need to synchronize because all adds are done sequentially |
| // before any implies() calls |
| perms.add(permission); |
| |
| } |
| } |
| |
| /** |
| * Check whether this set of permissions implies the permission specified in |
| * the parameter. |
| * |
| * @param permission the Permission object to compare |
| * @return true if the parameter permission is a proper subset of the |
| * permissions in the collection, false otherwise |
| */ |
| public boolean implies(Permission permission) { |
| if (!(permission instanceof DmtPrincipalPermission)) |
| return false; |
| |
| DmtPrincipalPermission other = (DmtPrincipalPermission) permission; |
| |
| Iterator i = perms.iterator(); |
| while (i.hasNext()) |
| if (((DmtPrincipalPermission) i.next()).impliesPrincipal(other)) |
| return true; |
| |
| return false; |
| } |
| |
| /** |
| * Returns an enumeration of all the DmtPrincipalPermission objects in the |
| * container. The returned value cannot be <code>null</code>. |
| * |
| * @return an enumeration of all the DmtPrincipalPermission objects |
| */ |
| public Enumeration elements() { |
| // Convert Iterator into Enumeration |
| return Collections.enumeration(perms); |
| } |
| } |