src/share/classes/java/util/PropertyPermission.java

Print this page




 113      * The actions mask.
 114      *
 115      */
 116     private transient int mask;
 117 
 118     /**
 119      * The actions string.
 120      *
 121      * @serial
 122      */
 123     private String actions; // Left null as long as possible, then
 124                             // created and re-used in the getAction function.
 125 
 126     /**
 127      * initialize a PropertyPermission object. Common to all constructors.
 128      * Also called during de-serialization.
 129      *
 130      * @param mask the actions mask to use.
 131      *
 132      */
 133 
 134     private void init(int mask)
 135     {
 136 
 137         if ((mask & ALL) != mask)
 138                 throw new IllegalArgumentException("invalid actions mask");
 139 
 140         if (mask == NONE)
 141                 throw new IllegalArgumentException("invalid actions mask");
 142 
 143         if (getName() == null)
 144                 throw new NullPointerException("name can't be null");
 145 
 146         this.mask = mask;
 147     }
 148 
 149     /**
 150      * Creates a new PropertyPermission object with the specified name.
 151      * The name is the name of the system property, and
 152      * <i>actions</i> contains a comma-separated list of the
 153      * desired actions granted on the property. Possible actions are
 154      * "read" and "write".
 155      *
 156      * @param name the name of the PropertyPermission.
 157      * @param actions the actions string.
 158      *
 159      * @throws NullPointerException if <code>name</code> is <code>null</code>.
 160      * @throws IllegalArgumentException if <code>name</code> is empty or if
 161      * <code>actions</code> is invalid.
 162      */
 163 
 164     public PropertyPermission(String name, String actions)
 165     {
 166         super(name,actions);
 167         init(getMask(actions));
 168     }
 169 
 170     /**
 171      * Checks if this PropertyPermission object "implies" the specified
 172      * permission.
 173      * <P>
 174      * More specifically, this method returns true if:<p>
 175      * <ul>
 176      * <li> <i>p</i> is an instanceof PropertyPermission,<p>
 177      * <li> <i>p</i>'s actions are a subset of this
 178      * object's actions, and <p>
 179      * <li> <i>p</i>'s name is implied by this object's
 180      *      name. For example, "java.*" implies "java.home".
 181      * </ul>
 182      * @param p the permission to check against.
 183      *
 184      * @return true if the specified permission is implied by this object,
 185      * false if not.
 186      */
 187     public boolean implies(Permission p) {
 188         if (!(p instanceof PropertyPermission))
 189             return false;
 190 
 191         PropertyPermission that = (PropertyPermission) p;
 192 
 193         // we get the effective mask. i.e., the "and" of this and that.
 194         // They must be equal to that.mask for implies to return true.
 195 
 196         return ((this.mask & that.mask) == that.mask) && super.implies(that);
 197     }
 198 
 199 
 200     /**
 201      * Checks two PropertyPermission objects for equality. Checks that <i>obj</i> is
 202      * a PropertyPermission, and has the same name and actions as this object.
 203      * <P>
 204      * @param obj the object we are testing for equality with this object.
 205      * @return true if obj is a PropertyPermission, and has the same name and
 206      * actions as this PropertyPermission object.
 207      */
 208     public boolean equals(Object obj) {
 209         if (obj == this)
 210             return true;
 211 
 212         if (! (obj instanceof PropertyPermission))
 213             return false;
 214 
 215         PropertyPermission that = (PropertyPermission) obj;
 216 
 217         return (this.mask == that.mask) &&
 218             (this.getName().equals(that.getName()));
 219     }
 220 
 221     /**
 222      * Returns the hash code value for this object.
 223      * The hash code used is the hash code of this permissions name, that is,
 224      * <code>getName().hashCode()</code>, where <code>getName</code> is
 225      * from the Permission superclass.
 226      *
 227      * @return a hash code value for this object.
 228      */
 229 
 230     public int hashCode() {
 231         return this.getName().hashCode();
 232     }
 233 
 234 
 235     /**
 236      * Converts an actions String to an actions mask.
 237      *
 238      * @param action the action string.
 239      * @return the actions mask.
 240      */
 241     private static int getMask(String actions) {
 242 
 243         int mask = NONE;
 244 
 245         if (actions == null) {
 246             return mask;
 247         }
 248 
 249         // Use object identity comparison against known-interned strings for
 250         // performance benefit (these values are used heavily within the JDK).
 251         if (actions == SecurityConstants.PROPERTY_READ_ACTION) {
 252             return READ;
 253         } if (actions == SecurityConstants.PROPERTY_WRITE_ACTION) {
 254             return WRITE;
 255         } else if (actions == SecurityConstants.PROPERTY_RW_ACTION) {
 256             return READ|WRITE;
 257         }
 258 


 315                             "invalid permission: " + actions);
 316                 }
 317                 i--;
 318             }
 319 
 320             // point i at the location of the comma minus one (or -1).
 321             i -= matchlen;
 322         }
 323 
 324         return mask;
 325     }
 326 
 327 
 328     /**
 329      * Return the canonical string representation of the actions.
 330      * Always returns present actions in the following order:
 331      * read, write.
 332      *
 333      * @return the canonical string representation of the actions.
 334      */
 335     static String getActions(int mask)
 336     {
 337         StringBuilder sb = new StringBuilder();
 338         boolean comma = false;
 339 
 340         if ((mask & READ) == READ) {
 341             comma = true;
 342             sb.append("read");
 343         }
 344 
 345         if ((mask & WRITE) == WRITE) {
 346             if (comma) sb.append(',');
 347             else comma = true;
 348             sb.append("write");
 349         }
 350         return sb.toString();
 351     }
 352 
 353     /**
 354      * Returns the "canonical string representation" of the actions.
 355      * That is, this method always returns present actions in the following order:
 356      * read, write. For example, if this PropertyPermission object
 357      * allows both write and read actions, a call to <code>getActions</code>
 358      * will return the string "read,write".
 359      *
 360      * @return the canonical string representation of the actions.
 361      */
 362     public String getActions()
 363     {
 364         if (actions == null)
 365             actions = getActions(this.mask);
 366 
 367         return actions;
 368     }
 369 
 370     /**
 371      * Return the current action mask.
 372      * Used by the PropertyPermissionCollection
 373      *
 374      * @return the actions mask.
 375      */
 376 
 377     int getMask() {
 378         return mask;
 379     }
 380 
 381     /**
 382      * Returns a new PermissionCollection object for storing
 383      * PropertyPermission objects.
 384      * <p>
 385      *
 386      * @return a new PermissionCollection object suitable for storing
 387      * PropertyPermissions.
 388      */
 389 
 390     public PermissionCollection newPermissionCollection() {
 391         return new PropertyPermissionCollection();
 392     }
 393 
 394 
 395     private static final long serialVersionUID = 885438825399942851L;
 396 
 397     /**
 398      * WriteObject is called to save the state of the PropertyPermission
 399      * to a stream. The actions are serialized, and the superclass
 400      * takes care of the name.
 401      */
 402     private synchronized void writeObject(java.io.ObjectOutputStream s)
 403         throws IOException
 404     {
 405         // Write out the actions. The superclass takes care of the name
 406         // call getActions to make sure actions field is initialized
 407         if (actions == null)
 408             getActions();
 409         s.defaultWriteObject();


 419         // Read in the action, then initialize the rest
 420         s.defaultReadObject();
 421         init(getMask(actions));
 422     }
 423 }
 424 
 425 /**
 426  * A PropertyPermissionCollection stores a set of PropertyPermission
 427  * permissions.
 428  *
 429  * @see java.security.Permission
 430  * @see java.security.Permissions
 431  * @see java.security.PermissionCollection
 432  *
 433  *
 434  * @author Roland Schemers
 435  *
 436  * @serial include
 437  */
 438 final class PropertyPermissionCollection extends PermissionCollection
 439 implements Serializable
 440 {
 441 
 442     /**
 443      * Key is property name; value is PropertyPermission.
 444      * Not serialized; see serialization section at end of class.
 445      */
 446     private transient Map<String, PropertyPermission> perms;
 447 
 448     /**
 449      * Boolean saying if "*" is in the collection.
 450      *
 451      * @see #serialPersistentFields
 452      */
 453     // No sync access; OK for this to be stale.
 454     private boolean all_allowed;
 455 
 456     /**
 457      * Create an empty PropertyPermissions object.
 458      *
 459      */
 460 
 461     public PropertyPermissionCollection() {
 462         perms = new HashMap<>(32);     // Capacity for default policy
 463         all_allowed = false;
 464     }
 465 
 466     /**
 467      * Adds a permission to the PropertyPermissions. The key for the hash is
 468      * the name.
 469      *
 470      * @param permission the Permission object to add.
 471      *
 472      * @exception IllegalArgumentException - if the permission is not a
 473      *                                       PropertyPermission
 474      *
 475      * @exception SecurityException - if this PropertyPermissionCollection
 476      *                                object has been marked readonly
 477      */
 478 
 479     public void add(Permission permission)
 480     {
 481         if (! (permission instanceof PropertyPermission))
 482             throw new IllegalArgumentException("invalid permission: "+
 483                                                permission);
 484         if (isReadOnly())
 485             throw new SecurityException(
 486                 "attempt to add a Permission to a readonly PermissionCollection");
 487 
 488         PropertyPermission pp = (PropertyPermission) permission;
 489         String propName = pp.getName();
 490 
 491         synchronized (this) {
 492             PropertyPermission existing = perms.get(propName);
 493 
 494             if (existing != null) {
 495                 int oldMask = existing.getMask();
 496                 int newMask = pp.getMask();
 497                 if (oldMask != newMask) {
 498                     int effective = oldMask | newMask;
 499                     String actions = PropertyPermission.getActions(effective);
 500                     perms.put(propName, new PropertyPermission(propName, actions));
 501                 }
 502             } else {
 503                 perms.put(propName, pp);
 504             }
 505         }
 506 
 507         if (!all_allowed) {
 508             if (propName.equals("*"))
 509                 all_allowed = true;
 510         }
 511     }
 512 
 513     /**
 514      * Check and see if this set of permissions implies the permissions
 515      * expressed in "permission".
 516      *
 517      * @param p the Permission object to compare
 518      *
 519      * @return true if "permission" is a proper subset of a permission in
 520      * the set, false if not.
 521      */
 522 
 523     public boolean implies(Permission permission)
 524     {
 525         if (! (permission instanceof PropertyPermission))
 526                 return false;
 527 
 528         PropertyPermission pp = (PropertyPermission) permission;
 529         PropertyPermission x;
 530 
 531         int desired = pp.getMask();
 532         int effective = 0;
 533 
 534         // short circuit if the "*" Permission was added
 535         if (all_allowed) {
 536             synchronized (this) {
 537                 x = perms.get("*");
 538             }
 539             if (x != null) {
 540                 effective |= x.getMask();
 541                 if ((effective & desired) == desired)
 542                     return true;
 543             }
 544         }


 638         // Don't call out.defaultWriteObject()
 639 
 640         // Copy perms into a Hashtable
 641         Hashtable<String, Permission> permissions =
 642             new Hashtable<>(perms.size()*2);
 643         synchronized (this) {
 644             permissions.putAll(perms);
 645         }
 646 
 647         // Write out serializable fields
 648         ObjectOutputStream.PutField pfields = out.putFields();
 649         pfields.put("all_allowed", all_allowed);
 650         pfields.put("permissions", permissions);
 651         out.writeFields();
 652     }
 653 
 654     /*
 655      * Reads in a Hashtable of PropertyPermissions and saves them in the
 656      * perms field. Reads in all_allowed.
 657      */
 658     private void readObject(ObjectInputStream in) throws IOException,
 659     ClassNotFoundException {

 660         // Don't call defaultReadObject()
 661 
 662         // Read in serialized fields
 663         ObjectInputStream.GetField gfields = in.readFields();
 664 
 665         // Get all_allowed
 666         all_allowed = gfields.get("all_allowed", false);
 667 
 668         // Get permissions
 669         @SuppressWarnings("unchecked")
 670         Hashtable<String, PropertyPermission> permissions =
 671             (Hashtable<String, PropertyPermission>)gfields.get("permissions", null);
 672         perms = new HashMap<>(permissions.size()*2);
 673         perms.putAll(permissions);
 674     }
 675 }


 113      * The actions mask.
 114      *
 115      */
 116     private transient int mask;
 117 
 118     /**
 119      * The actions string.
 120      *
 121      * @serial
 122      */
 123     private String actions; // Left null as long as possible, then
 124                             // created and re-used in the getAction function.
 125 
 126     /**
 127      * initialize a PropertyPermission object. Common to all constructors.
 128      * Also called during de-serialization.
 129      *
 130      * @param mask the actions mask to use.
 131      *
 132      */
 133     private void init(int mask) {



 134         if ((mask & ALL) != mask)
 135             throw new IllegalArgumentException("invalid actions mask");
 136 
 137         if (mask == NONE)
 138             throw new IllegalArgumentException("invalid actions mask");
 139 
 140         if (getName() == null)
 141             throw new NullPointerException("name can't be null");
 142 
 143         this.mask = mask;
 144     }
 145 
 146     /**
 147      * Creates a new PropertyPermission object with the specified name.
 148      * The name is the name of the system property, and
 149      * <i>actions</i> contains a comma-separated list of the
 150      * desired actions granted on the property. Possible actions are
 151      * "read" and "write".
 152      *
 153      * @param name the name of the PropertyPermission.
 154      * @param actions the actions string.
 155      *
 156      * @throws NullPointerException if <code>name</code> is <code>null</code>.
 157      * @throws IllegalArgumentException if <code>name</code> is empty or if
 158      * <code>actions</code> is invalid.
 159      */
 160     public PropertyPermission(String name, String actions) {


 161         super(name,actions);
 162         init(getMask(actions));
 163     }
 164 
 165     /**
 166      * Checks if this PropertyPermission object "implies" the specified
 167      * permission.
 168      * <P>
 169      * More specifically, this method returns true if:<p>
 170      * <ul>
 171      * <li> <i>p</i> is an instanceof PropertyPermission,<p>
 172      * <li> <i>p</i>'s actions are a subset of this
 173      * object's actions, and <p>
 174      * <li> <i>p</i>'s name is implied by this object's
 175      *      name. For example, "java.*" implies "java.home".
 176      * </ul>
 177      * @param p the permission to check against.
 178      *
 179      * @return true if the specified permission is implied by this object,
 180      * false if not.
 181      */
 182     public boolean implies(Permission p) {
 183         if (!(p instanceof PropertyPermission))
 184             return false;
 185 
 186         PropertyPermission that = (PropertyPermission) p;
 187 
 188         // we get the effective mask. i.e., the "and" of this and that.
 189         // They must be equal to that.mask for implies to return true.
 190 
 191         return ((this.mask & that.mask) == that.mask) && super.implies(that);
 192     }
 193 

 194     /**
 195      * Checks two PropertyPermission objects for equality. Checks that <i>obj</i> is
 196      * a PropertyPermission, and has the same name and actions as this object.
 197      * <P>
 198      * @param obj the object we are testing for equality with this object.
 199      * @return true if obj is a PropertyPermission, and has the same name and
 200      * actions as this PropertyPermission object.
 201      */
 202     public boolean equals(Object obj) {
 203         if (obj == this)
 204             return true;
 205 
 206         if (! (obj instanceof PropertyPermission))
 207             return false;
 208 
 209         PropertyPermission that = (PropertyPermission) obj;
 210 
 211         return (this.mask == that.mask) &&
 212             (this.getName().equals(that.getName()));
 213     }
 214 
 215     /**
 216      * Returns the hash code value for this object.
 217      * The hash code used is the hash code of this permissions name, that is,
 218      * <code>getName().hashCode()</code>, where <code>getName</code> is
 219      * from the Permission superclass.
 220      *
 221      * @return a hash code value for this object.
 222      */

 223     public int hashCode() {
 224         return this.getName().hashCode();
 225     }
 226 

 227     /**
 228      * Converts an actions String to an actions mask.
 229      *
 230      * @param actions the action string.
 231      * @return the actions mask.
 232      */
 233     private static int getMask(String actions) {
 234 
 235         int mask = NONE;
 236 
 237         if (actions == null) {
 238             return mask;
 239         }
 240 
 241         // Use object identity comparison against known-interned strings for
 242         // performance benefit (these values are used heavily within the JDK).
 243         if (actions == SecurityConstants.PROPERTY_READ_ACTION) {
 244             return READ;
 245         } if (actions == SecurityConstants.PROPERTY_WRITE_ACTION) {
 246             return WRITE;
 247         } else if (actions == SecurityConstants.PROPERTY_RW_ACTION) {
 248             return READ|WRITE;
 249         }
 250 


 307                             "invalid permission: " + actions);
 308                 }
 309                 i--;
 310             }
 311 
 312             // point i at the location of the comma minus one (or -1).
 313             i -= matchlen;
 314         }
 315 
 316         return mask;
 317     }
 318 
 319 
 320     /**
 321      * Return the canonical string representation of the actions.
 322      * Always returns present actions in the following order:
 323      * read, write.
 324      *
 325      * @return the canonical string representation of the actions.
 326      */
 327     static String getActions(int mask) {

 328         StringBuilder sb = new StringBuilder();
 329         boolean comma = false;
 330 
 331         if ((mask & READ) == READ) {
 332             comma = true;
 333             sb.append("read");
 334         }
 335 
 336         if ((mask & WRITE) == WRITE) {
 337             if (comma) sb.append(',');
 338             else comma = true;
 339             sb.append("write");
 340         }
 341         return sb.toString();
 342     }
 343 
 344     /**
 345      * Returns the "canonical string representation" of the actions.
 346      * That is, this method always returns present actions in the following order:
 347      * read, write. For example, if this PropertyPermission object
 348      * allows both write and read actions, a call to <code>getActions</code>
 349      * will return the string "read,write".
 350      *
 351      * @return the canonical string representation of the actions.
 352      */
 353     public String getActions() {

 354         if (actions == null)
 355             actions = getActions(this.mask);
 356 
 357         return actions;
 358     }
 359 
 360     /**
 361      * Return the current action mask.
 362      * Used by the PropertyPermissionCollection
 363      *
 364      * @return the actions mask.
 365      */

 366     int getMask() {
 367         return mask;
 368     }
 369 
 370     /**
 371      * Returns a new PermissionCollection object for storing
 372      * PropertyPermission objects.
 373      * <p>
 374      *
 375      * @return a new PermissionCollection object suitable for storing
 376      * PropertyPermissions.
 377      */

 378     public PermissionCollection newPermissionCollection() {
 379         return new PropertyPermissionCollection();
 380     }
 381 
 382 
 383     private static final long serialVersionUID = 885438825399942851L;
 384 
 385     /**
 386      * WriteObject is called to save the state of the PropertyPermission
 387      * to a stream. The actions are serialized, and the superclass
 388      * takes care of the name.
 389      */
 390     private synchronized void writeObject(java.io.ObjectOutputStream s)
 391         throws IOException
 392     {
 393         // Write out the actions. The superclass takes care of the name
 394         // call getActions to make sure actions field is initialized
 395         if (actions == null)
 396             getActions();
 397         s.defaultWriteObject();


 407         // Read in the action, then initialize the rest
 408         s.defaultReadObject();
 409         init(getMask(actions));
 410     }
 411 }
 412 
 413 /**
 414  * A PropertyPermissionCollection stores a set of PropertyPermission
 415  * permissions.
 416  *
 417  * @see java.security.Permission
 418  * @see java.security.Permissions
 419  * @see java.security.PermissionCollection
 420  *
 421  *
 422  * @author Roland Schemers
 423  *
 424  * @serial include
 425  */
 426 final class PropertyPermissionCollection extends PermissionCollection
 427     implements Serializable
 428 {
 429 
 430     /**
 431      * Key is property name; value is PropertyPermission.
 432      * Not serialized; see serialization section at end of class.
 433      */
 434     private transient Map<String, PropertyPermission> perms;
 435 
 436     /**
 437      * Boolean saying if "*" is in the collection.
 438      *
 439      * @see #serialPersistentFields
 440      */
 441     // No sync access; OK for this to be stale.
 442     private boolean all_allowed;
 443 
 444     /**
 445      * Create an empty PropertyPermissionCollection object.

 446      */

 447     public PropertyPermissionCollection() {
 448         perms = new HashMap<>(32);     // Capacity for default policy
 449         all_allowed = false;
 450     }
 451 
 452     /**
 453      * Adds a permission to the PropertyPermissions. The key for the hash is
 454      * the name.
 455      *
 456      * @param permission the Permission object to add.
 457      *
 458      * @exception IllegalArgumentException - if the permission is not a
 459      *                                       PropertyPermission
 460      *
 461      * @exception SecurityException - if this PropertyPermissionCollection
 462      *                                object has been marked readonly
 463      */
 464     public void add(Permission permission) {


 465         if (! (permission instanceof PropertyPermission))
 466             throw new IllegalArgumentException("invalid permission: "+
 467                                                permission);
 468         if (isReadOnly())
 469             throw new SecurityException(
 470                 "attempt to add a Permission to a readonly PermissionCollection");
 471 
 472         PropertyPermission pp = (PropertyPermission) permission;
 473         String propName = pp.getName();
 474 
 475         synchronized (this) {
 476             PropertyPermission existing = perms.get(propName);
 477 
 478             if (existing != null) {
 479                 int oldMask = existing.getMask();
 480                 int newMask = pp.getMask();
 481                 if (oldMask != newMask) {
 482                     int effective = oldMask | newMask;
 483                     String actions = PropertyPermission.getActions(effective);
 484                     perms.put(propName, new PropertyPermission(propName, actions));
 485                 }
 486             } else {
 487                 perms.put(propName, pp);
 488             }
 489         }
 490 
 491         if (!all_allowed) {
 492             if (propName.equals("*"))
 493                 all_allowed = true;
 494         }
 495     }
 496 
 497     /**
 498      * Check and see if this set of permissions implies the permissions
 499      * expressed in "permission".
 500      *
 501      * @param permission the Permission object to compare
 502      *
 503      * @return true if "permission" is a proper subset of a permission in
 504      * the set, false if not.
 505      */
 506     public boolean implies(Permission permission) {


 507         if (! (permission instanceof PropertyPermission))
 508                 return false;
 509 
 510         PropertyPermission pp = (PropertyPermission) permission;
 511         PropertyPermission x;
 512 
 513         int desired = pp.getMask();
 514         int effective = 0;
 515 
 516         // short circuit if the "*" Permission was added
 517         if (all_allowed) {
 518             synchronized (this) {
 519                 x = perms.get("*");
 520             }
 521             if (x != null) {
 522                 effective |= x.getMask();
 523                 if ((effective & desired) == desired)
 524                     return true;
 525             }
 526         }


 620         // Don't call out.defaultWriteObject()
 621 
 622         // Copy perms into a Hashtable
 623         Hashtable<String, Permission> permissions =
 624             new Hashtable<>(perms.size()*2);
 625         synchronized (this) {
 626             permissions.putAll(perms);
 627         }
 628 
 629         // Write out serializable fields
 630         ObjectOutputStream.PutField pfields = out.putFields();
 631         pfields.put("all_allowed", all_allowed);
 632         pfields.put("permissions", permissions);
 633         out.writeFields();
 634     }
 635 
 636     /*
 637      * Reads in a Hashtable of PropertyPermissions and saves them in the
 638      * perms field. Reads in all_allowed.
 639      */
 640     private void readObject(ObjectInputStream in)
 641         throws IOException, ClassNotFoundException
 642     {
 643         // Don't call defaultReadObject()
 644 
 645         // Read in serialized fields
 646         ObjectInputStream.GetField gfields = in.readFields();
 647 
 648         // Get all_allowed
 649         all_allowed = gfields.get("all_allowed", false);
 650 
 651         // Get permissions
 652         @SuppressWarnings("unchecked")
 653         Hashtable<String, PropertyPermission> permissions =
 654             (Hashtable<String, PropertyPermission>)gfields.get("permissions", null);
 655         perms = new HashMap<>(permissions.size()*2);
 656         perms.putAll(permissions);
 657     }
 658 }