package fr.mch.mdo.restaurant.services.authorization.jaas;
/*
* @(#)FilePermission.java 1.69 01/12/03
*
* Copyright 2002 Sun Microsystems, Inc. All rights reserved.
* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
import java.io.Serializable;
import java.security.BasicPermission;
import java.security.Permission;
import java.security.PermissionCollection;
import java.util.Enumeration;
import java.util.Vector;
/**
* This class represents access to a file or directory. A FilePermission
* consists of a pathname and a set of actions valid for that pathname.
* <P>
* Pathname is the pathname of the file or directory granted the specified
* actions. A pathname that ends in "/*" (where "/" is the file separator
* character, <code>File.separatorChar</code>) indicates all the files and
* directories contained in that directory. A pathname that ends with "/-"
* indicates (recursively) all files and subdirectories contained in that
* directory. A pathname consisting of the special token "<<ALL
* FILES>>" matches <b>any</b> file.
* <P>
* Note: A pathname consisting of a single "*" indicates all the files in the
* current directory, while a pathname consisting of a single "-" indicates all
* the files in the current directory and (recursively) all files and
* subdirectories contained in the current directory.
* <P>
* The actions to be granted are passed to the constructor in a string
* containing a list of one or more comma-separated keywords. The possible
* keywords are "read", "write", "execute", and "delete". Their meaning is
* defined as follows:
* <P>
* <DL>
* <DT> read
* <DD> read permission
* <DT> write
* <DD> write permission
* <DT> execute
* <DD> execute permission. Allows <code>Runtime.exec</code> to be called.
* Corresponds to <code>SecurityManager.checkExec</code>.
* <DT> delete
* <DD> delete permission. Allows <code>File.delete</code> to be called.
* Corresponds to <code>SecurityManager.checkDelete</code>.
* </DL>
* <P>
* The actions string is converted to lowercase before processing.
* <P>
* Be careful when granting FilePermissions. Think about the implications of
* granting read and especially write access to various files and directories.
* The "<<ALL FILES>>" permission with write action is especially
* dangerous. This grants permission to write to the entire file system. One
* thing this effectively allows is replacement of the system binary, including
* the JVM runtime environment.
*
* <p>
* Please note: Code can always read a file from the same directory it's in (or
* a subdirectory of that directory); it does not need explicit permission to do
* so.
*
* @see java.security.Permission
* @see java.security.Permissions
* @see java.security.PermissionCollection
*
* @version 1.69 01/12/03
*
* @author Marianne Mueller
* @author Roland Schemers
* @since 1.2
*
* @serial exclude
*/
public final class URLPermission extends BasicPermission implements Serializable
{
/**
* Default Serial Version UID.
*/
private static final long serialVersionUID = -9169439454066563567L;
/**
* the actions string.
*
* @serial
*/
private String actions; // Left null as long as possible, then
private String url = null;
/**
* Creates a new FilePermission object with the specified actions. <i>path</i>
* is the pathname of a file or directory, and <i>actions</i> contains a
* comma-separated list of the desired actions granted on the file or
* directory. Possible actions are "read", "write", "execute", and "delete".
*
* <p>
* A pathname that ends in "/*" (where "/" is the file separator character,
* <code>File.separatorChar</code>) indicates a directory and all the
* files contained in that directory. A pathname that ends with "/-"
* indicates a directory and (recursively) all files and subdirectories
* contained in that directory. The special pathname "<<ALL
* FILES>>" matches all files.
*
* <p>
* A pathname consisting of a single "*" indicates all the files in the
* current directory, while a pathname consisting of a single "-" indicates
* all the files in the current directory and (recursively) all files and
* subdirectories contained in the current directory.
*
* @param path
* the pathname of the file/directory.
* @param actions
* the action string.
*/
public URLPermission(String path) {
super(path);
url = path;
}
public URLPermission(String path, String actions) {
super(path, actions);
url = path;
}
/**
* Checks if this FilePermission object "implies" the specified permission.
* <P>
* More specifically, this method returns true if:
* <p>
* <ul>
* <li> <i>p</i> is an instanceof FilePermission,
* <p>
* <li> <i>p</i>'s actions are a proper subset of this object's actions,
* and
* <p>
* <li> <i>p</i>'s pathname is implied by this object's pathname. For
* example, "/tmp/*" implies "/tmp/foo", since "/tmp/*" encompasses the
* "/tmp" directory and all files in that directory, including the one named
* "foo".
* </ul>
*
* @param p
* the permission to check against.
*
* @return true if the specified permission is implied by this object, false
* if not.
*/
public boolean implies(Permission p) {
if (p == this) {
return true;
}
if (!(p instanceof URLPermission)) {
return false;
}
if (this.equals(p)) {
return true;
} else {
return false;
}
}
@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
result = prime * result + ((url == null) ? 0 : url.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!super.equals(obj)) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
URLPermission other = (URLPermission) obj;
if (url == null) {
if (other.url != null) {
return false;
}
} else if (!url.equals(other.url)) {
return false;
}
return true;
}
/**
* Returns the "canonical string representation" of the actions. That is,
* this method always returns present actions in the following order: read,
* write, execute, delete. For example, if this FilePermission object allows
* both write and read actions, a call to <code>getActions</code> will
* return the string "read,write".
*
* @return the canonical string representation of the actions.
*/
public String getActions() {
return actions;
}
/**
* Returns a new PermissionCollection object for storing FilePermission
* objects.
* <p>
* FilePermission objects must be stored in a manner that allows them to be
* inserted into the collection in any order, but that also enables the
* PermissionCollection <code>implies</code> method to be implemented in
* an efficient (and consistent) manner.
*
* <p>
* For example, if you have two FilePermissions:
* <OL>
* <LI> <code>"/tmp/-", "read"</code>
* <LI> <code>"/tmp/scratch/foo", "write"</code>
* </OL>
*
* <p>
* and you are calling the <code>implies</code> method with the
* FilePermission:
*
* <pre>
* "/tmp/scratch/foo", "read,write",
* </pre>
*
* then the <code>implies</code> function must take into account both the
* "/tmp/-" and "/tmp/scratch/foo" permissions, so the effective permission
* is "read,write", and <code>implies</code> returns true. The "implies"
* semantics for FilePermissions are handled properly by the
* PermissionCollection object returned by this
* <code>newPermissionCollection</code> method.
*
* @return a new PermissionCollection object suitable for storing
* FilePermissions.
*/
public PermissionCollection newPermissionCollection() {
return new URLPermissionCollection();
}
}
final class URLPermissionCollection extends PermissionCollection implements Serializable
{
/**
* Default Serial Version UID.
*/
private static final long serialVersionUID = 1L;
private Vector<Permission> permissions;
/**
* Create an empty FilePermissions object.
*
*/
public URLPermissionCollection() {
permissions = new Vector<Permission>();
}
/**
* Adds a permission to the FilePermissions. The key for the hash is
* permission.path.
*
* @param permission
* the Permission object to add.
*
* @exception IllegalArgumentException -
* if the permission is not a FilePermission
*
* @exception SecurityException -
* if this FilePermissionCollection object has been
* marked readonly
*/
public void add(Permission permission) {
if (!(permission instanceof URLPermission)) {
throw new IllegalArgumentException("Invalid permission: " + permission);
}
if (isReadOnly()) {
throw new SecurityException("Attempt to add a Permission to a readonly PermissionCollection");
}
permissions.addElement((URLPermission) permission);
}
/**
* Check and see if this set of permissions implies the permissions
* expressed in "permission".
*
* @param p
* the Permission object to compare
*
* @return true if "permission" is a proper subset of a permission in the
* set, false if not.
*/
public boolean implies(Permission permission) {
if (!(permission instanceof URLPermission)) {
return false;
}
URLPermission fp = (URLPermission) permission;
Enumeration<Permission> e = permissions.elements();
while (e.hasMoreElements()) {
URLPermission x = (URLPermission) e.nextElement();
if (x.implies(fp)) {
return true;
}
}
return false;
}
/**
* Returns an enumeration of all the FilePermission objects in the
* container.
*
* @return an enumeration of all the FilePermission objects.
*/
public Enumeration<Permission> elements() {
return permissions.elements();
}
}