Frames | No Frames |
1: /* PrivateCredentialPermission.java -- permissions governing private credentials. 2: Copyright (C) 2004 Free Software Foundation, Inc. 3: 4: This file is part of GNU Classpath. 5: 6: GNU Classpath is free software; you can redistribute it and/or modify 7: it under the terms of the GNU General Public License as published by 8: the Free Software Foundation; either version 2, or (at your option) 9: any later version. 10: 11: GNU Classpath is distributed in the hope that it will be useful, but 12: WITHOUT ANY WARRANTY; without even the implied warranty of 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14: General Public License for more details. 15: 16: You should have received a copy of the GNU General Public License 17: along with GNU Classpath; see the file COPYING. If not, write to the 18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19: 02110-1301 USA. 20: 21: Linking this library statically or dynamically with other modules is 22: making a combined work based on this library. Thus, the terms and 23: conditions of the GNU General Public License cover the whole 24: combination. 25: 26: As a special exception, the copyright holders of this library give you 27: permission to link this library with independent modules to produce an 28: executable, regardless of the license terms of these independent 29: modules, and to copy and distribute the resulting executable under 30: terms of your choice, provided that you also meet, for each linked 31: independent module, the terms and conditions of the license of that 32: module. An independent module is a module which is not derived from 33: or based on this library. If you modify this library, you may extend 34: this exception to your version of the library, but you are not 35: obligated to do so. If you do not wish to do so, delete this 36: exception statement from your version. */ 37: 38: 39: package javax.security.auth; 40: 41: import java.io.Serializable; 42: 43: import java.security.Permission; 44: import java.security.PermissionCollection; 45: 46: import java.util.HashSet; 47: import java.util.Iterator; 48: import java.util.Set; 49: import java.util.StringTokenizer; 50: 51: /** 52: * A permission governing access to a private credential. The action of this 53: * permission is always "read" -- meaning that the private credential 54: * information can be read from an object. 55: * 56: * <p>The target of this permission is formatted as follows:</p> 57: * 58: * <p><code>CredentialClassName ( PrinicpalClassName PrincipalName )*</code></p> 59: * 60: * <p><i>CredentialClassName</i> is either the name of a private credential 61: * class name, or a wildcard character (<code>'*'</code>). 62: * <i>PrinicpalClassName</i> is the class name of a principal object, and 63: * <i>PrincipalName</i> is a string representing the principal, or the 64: * wildcard character.</p> 65: */ 66: public final class PrivateCredentialPermission extends Permission 67: implements Serializable 68: { 69: /** 70: * For compatability with Sun's JDK 1.4.2 rev. 5 71: */ 72: private static final long serialVersionUID = 5284372143517237068L; 73: 74: // Fields. 75: // ------------------------------------------------------------------------- 76: 77: /** 78: * @serial The credential class name. 79: */ 80: private final String credentialClass; 81: 82: /** 83: * @serial The principals, a set of CredOwner objects (an undocumented 84: * inner class of this class). 85: */ 86: private final Set principals; 87: 88: /** 89: * @serial Who knows? 90: */ 91: private final boolean testing; 92: 93: // Constructor. 94: // ------------------------------------------------------------------------- 95: 96: /** 97: * Create a new private credential permission. 98: * 99: * @param name The permission target name. 100: * @param actions The list of actions, which, for this class, must be 101: * <code>"read"</code>. 102: */ 103: public PrivateCredentialPermission (final String name, String actions) 104: { 105: super(name); 106: actions = actions.trim().toLowerCase(); 107: if (!"read".equals (actions)) 108: { 109: throw new IllegalArgumentException("actions must be \"read\""); 110: } 111: StringTokenizer st = new StringTokenizer (name, " \"'"); 112: principals = new HashSet(); 113: if (st.countTokens() < 3 || (st.countTokens() & 1) == 0) 114: { 115: throw new IllegalArgumentException ("badly formed credential name"); 116: } 117: credentialClass = st.nextToken(); 118: while (st.hasMoreTokens()) 119: { 120: principals.add (new CredOwner (st.nextToken(), st.nextToken())); 121: } 122: testing = false; // WTF ever. 123: } 124: 125: // Instance methods. 126: // ------------------------------------------------------------------------- 127: 128: public boolean equals (Object o) 129: { 130: if (! (o instanceof PrivateCredentialPermission)) 131: { 132: return false; 133: } 134: PrivateCredentialPermission that = (PrivateCredentialPermission) o; 135: if (!that.getActions().equals (getActions())) 136: { 137: return false; 138: } 139: if (!that.getCredentialClass().equals (getCredentialClass())) 140: { 141: return false; 142: } 143: 144: final String[][] principals = getPrincipals(); 145: final String[][] that_principals = that.getPrincipals(); 146: if (that_principals == null) 147: { 148: return false; 149: } 150: if (that_principals.length != principals.length) 151: { 152: return false; 153: } 154: for (int i = 0; i < principals.length; i++) 155: { 156: if (!principals[i][0].equals (that_principals[i][0]) || 157: !principals[i][1].equals (that_principals[i][1])) 158: { 159: return false; 160: } 161: } 162: return true; 163: } 164: 165: /** 166: * Returns the actions this permission encompasses. For private credential 167: * permissions, this is always the string <code>"read"</code>. 168: * 169: * @return The list of actions. 170: */ 171: public String getActions() 172: { 173: return "read"; 174: } 175: 176: /** 177: * Returns the credential class name that was embedded in this permission's 178: * target name. 179: * 180: * @return The credential class name. 181: */ 182: public String getCredentialClass() 183: { 184: return credentialClass; 185: } 186: 187: /** 188: * Returns the principal list that was embedded in this permission's target 189: * name. 190: * 191: * <p>Each element of the returned array is a pair; the first element is the 192: * principal class name, and the second is the principal name. 193: * 194: * @return The principal list. 195: */ 196: public String[][] getPrincipals() 197: { 198: String[][] ret = new String[principals.size()][]; 199: Iterator it = principals.iterator(); 200: for (int i = 0; i < principals.size() && it.hasNext(); i++) 201: { 202: CredOwner co = (CredOwner) it.next(); 203: ret[i] = new String[] { co.getPrincipalClass(), co.getPrincipalName() }; 204: } 205: return ret; 206: } 207: 208: public int hashCode() 209: { 210: return credentialClass.hashCode() + principals.hashCode(); 211: } 212: 213: /** 214: * Test if this permission implies another. This method returns true if: 215: * 216: * <ol> 217: * <li><i>p</i> is an instance of PrivateCredentialPermission</li>. 218: * <li>The credential class name of this instance matches that of <i>p</i>, 219: * and one of the principals of <i>p</i> is contained in the principals of 220: * this class. Thus, 221: * <ul> 222: * <li><code>[ * P "foo" ] implies [ C P "foo" ]</code></li> 223: * <li><code>[ C P1 "foo" ] implies [ C P1 "foo" P2 "bar" ]</code></li> 224: * <li><code>[ C P1 "*" ] implies [ C P1 "foo" ]</code></li> 225: * </ul> 226: * </ol> 227: * 228: * @param p The permission to check. 229: * @return True if this permission implies <i>p</i>. 230: */ 231: public boolean implies (Permission p) 232: { 233: if (! (p instanceof PrivateCredentialPermission)) 234: { 235: return false; 236: } 237: PrivateCredentialPermission that = (PrivateCredentialPermission) p; 238: if (!credentialClass.equals ("*") 239: && !credentialClass.equals (that.getCredentialClass())) 240: { 241: return false; 242: } 243: String[][] principals = getPrincipals(); 244: String[][] that_principals = that.getPrincipals(); 245: if (that_principals == null) 246: { 247: return false; 248: } 249: for (int i = 0; i < principals.length; i++) 250: { 251: for (int j = 0; j < that_principals.length; j++) 252: { 253: if (principals[i][0].equals (that_principals[j][0]) && 254: (principals[i][1].equals ("*") || 255: principals[i][1].equals (that_principals[j][1]))) 256: { 257: return true; 258: } 259: } 260: } 261: return false; 262: } 263: 264: /** 265: * This method is not necessary for this class, thus it always returns null. 266: * 267: * @return null. 268: */ 269: public PermissionCollection newPermissionCollection() 270: { 271: return null; 272: } 273: 274: // Inner class. 275: // ------------------------------------------------------------------------- 276: 277: /** 278: * An undocumented inner class present for serialization compatibility. 279: */ 280: private static class CredOwner implements Serializable 281: { 282: 283: // Fields. 284: // ----------------------------------------------------------------------- 285: 286: private final String principalClass; 287: private final String principalName; 288: 289: // Constructor. 290: // ----------------------------------------------------------------------- 291: 292: CredOwner (final String principalClass, final String principalName) 293: { 294: this.principalClass = principalClass; 295: this.principalName = principalName; 296: } 297: 298: // Instance methods. 299: // ----------------------------------------------------------------------- 300: 301: public boolean equals (Object o) 302: { 303: if (!(o instanceof CredOwner)) 304: { 305: return false; 306: } 307: return principalClass.equals (((CredOwner) o).getPrincipalClass()) && 308: principalName.equals (((CredOwner) o).getPrincipalName()); 309: } 310: 311: public int hashCode() 312: { 313: return principalClass.hashCode() + principalName.hashCode(); 314: } 315: 316: public String getPrincipalClass() 317: { 318: return principalClass; 319: } 320: 321: public String getPrincipalName() 322: { 323: return principalName; 324: } 325: } 326: }