BasicPermission.java 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. /* BasicPermission.java -- implements a simple named permission
  2. Copyright (C) 1998, 1999, 2002 Free Software Foundation, Inc.
  3. This file is part of GNU Classpath.
  4. GNU Classpath is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2, or (at your option)
  7. any later version.
  8. GNU Classpath is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with GNU Classpath; see the file COPYING. If not, write to the
  14. Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  15. 02111-1307 USA.
  16. Linking this library statically or dynamically with other modules is
  17. making a combined work based on this library. Thus, the terms and
  18. conditions of the GNU General Public License cover the whole
  19. combination.
  20. As a special exception, the copyright holders of this library give you
  21. permission to link this library with independent modules to produce an
  22. executable, regardless of the license terms of these independent
  23. modules, and to copy and distribute the resulting executable under
  24. terms of your choice, provided that you also meet, for each linked
  25. independent module, the terms and conditions of the license of that
  26. module. An independent module is a module which is not derived from
  27. or based on this library. If you modify this library, you may extend
  28. this exception to your version of the library, but you are not
  29. obligated to do so. If you do not wish to do so, delete this
  30. exception statement from your version. */
  31. package java.security;
  32. import java.io.Serializable;
  33. import java.util.Hashtable;
  34. import java.util.Enumeration;
  35. /**
  36. * This class implements a simple model for named permissions without an
  37. * associated action list. That is, either the named permission is granted
  38. * or it is not.
  39. *
  40. * <p>It also supports trailing wildcards to allow the easy granting of
  41. * permissions in a hierarchical fashion. (For example, the name "org.gnu.*"
  42. * might grant all permissions under the "org.gnu" permissions hierarchy).
  43. * The only valid wildcard character is a '*' which matches anything. It
  44. * must be the rightmost element in the permission name and must follow a
  45. * '.' or else the Permission name must consist of only a '*'. Any other
  46. * occurrence of a '*' is not valid.
  47. *
  48. * <p>This class ignores the action list. Subclasses can choose to implement
  49. * actions on top of this class if desired.
  50. *
  51. * @author Aaron M. Renn <arenn@urbanophile.com>
  52. * @author Eric Blake <ebb9@email.byu.edu>
  53. * @see Permission
  54. * @see Permissions
  55. * @see PermissionCollection
  56. * @see RuntimePermission
  57. * @see SecurityPermission
  58. * @see PropertyPermission
  59. * @see AWTPermission
  60. * @see NetPermission
  61. * @see SecurityManager
  62. * @since 1.1
  63. * @status updated to 1.4
  64. */
  65. public abstract class BasicPermission extends java.security.Permission
  66. implements Serializable
  67. // FIXME extends with fully qualified classname is workaround for gcj 3.0.4.
  68. {
  69. /**
  70. * Compatible with JDK 1.1+.
  71. */
  72. private static final long serialVersionUID = 6279438298436773498L;
  73. /**
  74. * Create a new instance with the specified permission name. If the name
  75. * is empty, or contains an illegal wildcard character, an exception is
  76. * thrown.
  77. *
  78. * @param name the name of this permission
  79. * @throws NullPointerException if name is null
  80. * @throws IllegalArgumentException if name is invalid
  81. */
  82. public BasicPermission(String name)
  83. {
  84. super(name);
  85. if (name.indexOf("*") != -1)
  86. {
  87. if ((! name.endsWith(".*") && ! name.equals("*"))
  88. || name.indexOf("*") != name.lastIndexOf("*"))
  89. throw new IllegalArgumentException("Bad wildcard: " + name);
  90. }
  91. if ("".equals(name))
  92. throw new IllegalArgumentException("Empty name");
  93. }
  94. /**
  95. * Create a new instance with the specified permission name. If the name
  96. * is empty, or contains an illegal wildcard character, an exception is
  97. * thrown. The actions parameter is ignored.
  98. *
  99. * @param name the name of this permission
  100. * @param actions ignored
  101. * @throws NullPointerException if name is null
  102. * @throws IllegalArgumentException if name is invalid
  103. */
  104. public BasicPermission(String name, String actions)
  105. {
  106. this(name);
  107. }
  108. /**
  109. * This method tests to see if the specified permission is implied by this
  110. * permission. This will be true if the following conditions are met:<ul>
  111. * <li>The specified object is an instance of the same class as this
  112. * object.</li>
  113. * <li>The name of the specified permission is implied by this permission's
  114. * name based on wildcard matching. For example, "a.*" implies "a.b".</li>
  115. * </ul>
  116. *
  117. * @param perm the <code>Permission</code> object to test against
  118. * @return true if the specified permission is implied
  119. */
  120. public boolean implies(Permission perm)
  121. {
  122. if (! getClass().isInstance(perm))
  123. return false;
  124. String otherName = perm.getName();
  125. String name = getName();
  126. if (name.equals(otherName))
  127. return true;
  128. int last = name.length() - 1;
  129. return name.charAt(last) == '*'
  130. && otherName.startsWith(name.substring(0, last));
  131. }
  132. /**
  133. * This method tests to see if this object is equal to the specified
  134. * <code>Object</code>. This will be true if and only if the specified
  135. * object meets the following conditions:<ul>
  136. * <li>It is an instance of the same class as this.</li>
  137. * <li>It has the same name as this permission.</li>
  138. * </ul>
  139. *
  140. * @param obj the <code>Object</code> to test for equality
  141. * @return true if obj is semantically equal to this
  142. */
  143. public boolean equals(Object obj)
  144. {
  145. return getClass().isInstance(obj)
  146. && getName().equals(((BasicPermission) obj).getName());
  147. }
  148. /**
  149. * This method returns a hash code for this permission object. The hash
  150. * code returned is the value returned by calling the <code>hashCode</code>
  151. * method on the <code>String</code> that is the name of this permission.
  152. *
  153. * @return a hash value for this object
  154. */
  155. public int hashCode()
  156. {
  157. return getName().hashCode();
  158. }
  159. /**
  160. * This method returns a list of the actions associated with this
  161. * permission. This method always returns the empty string ("") since
  162. * this class ignores actions.
  163. *
  164. * @return the action list
  165. */
  166. public String getActions()
  167. {
  168. return "";
  169. }
  170. /**
  171. * This method returns an instance of <code>PermissionCollection</code>
  172. * suitable for storing <code>BasicPermission</code> objects. The
  173. * collection returned can only store objects of the same type as this.
  174. * Subclasses which use actions must override this method; but a class with
  175. * no actions will work fine with this.
  176. *
  177. * @return a new empty <code>PermissionCollection</code> object
  178. */
  179. public PermissionCollection newPermissionCollection()
  180. {
  181. return new BasicPermissionCollection(getClass());
  182. }
  183. } // class BasicPermission
  184. /**
  185. * Implements AllPermission.newPermissionCollection, and obeys serialization
  186. * of JDK.
  187. *
  188. * @author Eric Blake <ebb9@email.byu.edu>
  189. */
  190. final class BasicPermissionCollection extends PermissionCollection
  191. {
  192. /**
  193. * Compatible with JDK 1.1+.
  194. */
  195. private static final long serialVersionUID = 739301742472979399L;
  196. /**
  197. * The permissions in the collection.
  198. *
  199. * @serial a hash mapping name to permissions, all of type permClass
  200. */
  201. private final Hashtable permissions = new Hashtable();
  202. /**
  203. * If "*" is in the collection.
  204. *
  205. * @serial true if a permission named "*" is in the collection
  206. */
  207. private boolean all_allowed;
  208. /**
  209. * The runtime class which all entries in the table must belong to.
  210. *
  211. * @serial the limiting subclass of this collection
  212. */
  213. private final Class permClass;
  214. /**
  215. * Construct a collection over the given runtime class.
  216. *
  217. * @param c the class
  218. */
  219. BasicPermissionCollection(Class c)
  220. {
  221. permClass = c;
  222. }
  223. /**
  224. * Add a Permission. It must be of the same type as the permission which
  225. * created this collection.
  226. *
  227. * @param perm the permission to add
  228. * @throws IllegalArgumentException if perm is not the correct type
  229. * @throws SecurityException if the collection is read-only
  230. */
  231. public void add(Permission perm)
  232. {
  233. if (isReadOnly())
  234. throw new SecurityException("readonly");
  235. if (! permClass.isInstance(perm))
  236. throw new IllegalArgumentException("Expecting instance of " + permClass);
  237. BasicPermission bp = (BasicPermission) perm;
  238. String name = bp.getName();
  239. if (name.equals("*"))
  240. all_allowed = true;
  241. permissions.put(name, bp);
  242. }
  243. /**
  244. * Returns true if this collection implies the given permission.
  245. *
  246. * @param permission the permission to check
  247. * @return true if it is implied by this
  248. */
  249. public boolean implies(Permission permission)
  250. {
  251. if (! permClass.isInstance(permission))
  252. return false;
  253. if (all_allowed)
  254. return true;
  255. BasicPermission toImply = (BasicPermission) permission;
  256. String name = toImply.getName();
  257. if (name.equals("*"))
  258. return false;
  259. int prefixLength = name.length();
  260. if (name.endsWith("*"))
  261. prefixLength -= 2;
  262. while (true)
  263. {
  264. if (permissions.get(name) != null)
  265. return true;
  266. prefixLength = name.lastIndexOf('.', prefixLength);
  267. if (prefixLength < 0)
  268. return false;
  269. name = name.substring(0, prefixLength + 1) + '*';
  270. }
  271. }
  272. /**
  273. * Enumerate over the collection.
  274. *
  275. * @return an enumeration of the collection contents
  276. */
  277. public Enumeration elements()
  278. {
  279. return permissions.elements();
  280. }
  281. } // class BasicPermissionCollection