1 /* 2 * Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.rmi.rmid; 27 28 import java.security.*; 29 import java.io.*; 30 import java.util.*; 31 32 /** 33 * The ExecOptionPermission class represents permission for rmid to use 34 * a specific command-line option when launching an activation group. 35 * <P> 36 * 37 * @author Ann Wollrath 38 * 39 * @serial exclude 40 */ 41 public final class ExecOptionPermission extends Permission 42 { 43 /** 44 * does this permission have a wildcard at the end? 45 */ 46 private transient boolean wildcard; 47 48 /** 49 * the name without the wildcard on the end 50 */ 51 private transient String name; 52 53 /** 54 * UID for serialization 55 */ 56 private static final long serialVersionUID = 5842294756823092756L; 57 58 public ExecOptionPermission(String name) { 59 super(name); 60 init(name); 61 } 62 63 public ExecOptionPermission(String name, String actions) { 64 this(name); 65 } 66 67 /** 68 * Checks if the specified permission is "implied" by 69 * this object. 70 * <P> 71 * More specifically, this method returns true if:<p> 72 * <ul> 73 * <li> <i>p</i>'s class is the same as this object's class, and<p> 74 * <li> <i>p</i>'s name equals or (in the case of wildcards) 75 * is implied by this object's 76 * name. For example, "a.b.*" implies "a.b.c", and 77 * "a.b=*" implies "a.b=c" 78 * </ul> 79 * 80 * @param p the permission to check against. 81 * 82 * @return true if the passed permission is equal to or 83 * implied by this permission, false otherwise. 84 */ 85 public boolean implies(Permission p) { 86 if (!(p instanceof ExecOptionPermission)) 87 return false; 88 89 ExecOptionPermission that = (ExecOptionPermission) p; 90 91 if (this.wildcard) { 92 if (that.wildcard) { 93 // one wildcard can imply another 94 return that.name.startsWith(name); 95 } else { 96 // make sure p.name is longer so a.b.* doesn't imply a.b 97 return (that.name.length() > this.name.length()) && 98 that.name.startsWith(this.name); 99 } 100 } else { 101 if (that.wildcard) { 102 // a non-wildcard can't imply a wildcard 103 return false; 104 } else { 105 return this.name.equals(that.name); 106 } 107 } 108 } 109 110 /** 111 * Checks two ExecOptionPermission objects for equality. 112 * Checks that <i>obj</i>'s class is the same as this object's class 113 * and has the same name as this object. 114 * <P> 115 * @param obj the object we are testing for equality with this object. 116 * @return true if <i>obj</i> is an ExecOptionPermission, and has the same 117 * name as this ExecOptionPermission object, false otherwise. 118 */ 119 public boolean equals(Object obj) { 120 if (obj == this) 121 return true; 122 123 if ((obj == null) || (obj.getClass() != getClass())) 124 return false; 125 126 ExecOptionPermission that = (ExecOptionPermission) obj; 127 128 return this.getName().equals(that.getName()); 129 } 130 131 132 /** 133 * Returns the hash code value for this object. 134 * The hash code used is the hash code of the name, that is, 135 * <code>getName().hashCode()</code>, where <code>getName</code> is 136 * from the Permission superclass. 137 * 138 * @return a hash code value for this object. 139 */ 140 public int hashCode() { 141 return this.getName().hashCode(); 142 } 143 144 /** 145 * Returns the canonical string representation of the actions. 146 * 147 * @return the canonical string representation of the actions. 148 */ 149 public String getActions() { 150 return ""; 151 } 152 153 /** 154 * Returns a new PermissionCollection object for storing 155 * ExecOptionPermission objects. 156 * <p> 157 * A ExecOptionPermissionCollection stores a collection of 158 * ExecOptionPermission permissions. 159 * 160 * <p>ExecOptionPermission objects must be stored in a manner that allows 161 * them to be inserted in any order, but that also enables the 162 * PermissionCollection <code>implies</code> method 163 * to be implemented in an efficient (and consistent) manner. 164 * 165 * @return a new PermissionCollection object suitable for 166 * storing ExecOptionPermissions. 167 */ 168 public PermissionCollection newPermissionCollection() { 169 return new ExecOptionPermissionCollection(); 170 } 171 172 /** 173 * readObject is called to restore the state of the ExecOptionPermission 174 * from a stream. 175 */ 176 private synchronized void readObject(java.io.ObjectInputStream s) 177 throws IOException, ClassNotFoundException 178 { 179 s.defaultReadObject(); 180 // init is called to initialize the rest of the values. 181 init(getName()); 182 } 183 184 /** 185 * Initialize a ExecOptionPermission object. Common to all constructors. 186 * Also called during de-serialization. 187 */ 188 private void init(String name) 189 { 190 if (name == null) 191 throw new NullPointerException("name can't be null"); 192 193 if (name.equals("")) { 194 throw new IllegalArgumentException("name can't be empty"); 195 } 196 197 if (name.endsWith(".*") || name.endsWith("=*") || name.equals("*")) { 198 wildcard = true; 199 if (name.length() == 1) { 200 this.name = ""; 201 } else { 202 this.name = name.substring(0, name.length()-1); 203 } 204 } else { 205 this.name = name; 206 } 207 } 208 209 /** 210 * A ExecOptionPermissionCollection stores a collection 211 * of ExecOptionPermission permissions. ExecOptionPermission objects 212 * must be stored in a manner that allows them to be inserted in any 213 * order, but enable the implies function to evaluate the implies 214 * method in an efficient (and consistent) manner. 215 * 216 * A ExecOptionPermissionCollection handles comparing a permission like 217 * "a.b.c.d.e" * with a Permission such as "a.b.*", or "*". 218 * 219 * @serial include 220 */ 221 private static class ExecOptionPermissionCollection 222 extends PermissionCollection 223 implements java.io.Serializable 224 { 225 226 private Hashtable permissions; 227 private boolean all_allowed; // true if "*" is in the collection 228 private static final long serialVersionUID = -1242475729790124375L; 229 230 /** 231 * Create an empty ExecOptionPermissionCollection. 232 */ 233 public ExecOptionPermissionCollection() { 234 permissions = new Hashtable(11); 235 all_allowed = false; 236 } 237 238 /** 239 * Adds a permission to the collection. The key for the hash is 240 * permission.name. 241 * 242 * @param permission the Permission object to add. 243 * 244 * @exception IllegalArgumentException - if the permission is not a 245 * ExecOptionPermission 246 * 247 * @exception SecurityException - if this ExecOptionPermissionCollection 248 * object has been marked readonly 249 */ 250 251 public void add(Permission permission) 252 { 253 if (! (permission instanceof ExecOptionPermission)) 254 throw new IllegalArgumentException("invalid permission: "+ 255 permission); 256 if (isReadOnly()) 257 throw new SecurityException("attempt to add a Permission to a readonly PermissionCollection"); 258 259 ExecOptionPermission p = (ExecOptionPermission) permission; 260 261 permissions.put(p.getName(), permission); 262 if (!all_allowed) { 263 if (p.getName().equals("*")) 264 all_allowed = true; 265 } 266 } 267 268 /** 269 * Check and see if this set of permissions implies the permissions 270 * expressed in "permission". 271 * 272 * @param p the Permission object to compare 273 * 274 * @return true if "permission" is a proper subset of a permission in 275 * the set, false if not. 276 */ 277 public boolean implies(Permission permission) 278 { 279 if (! (permission instanceof ExecOptionPermission)) 280 return false; 281 282 ExecOptionPermission p = (ExecOptionPermission) permission; 283 284 // short circuit if the "*" Permission was added 285 if (all_allowed) 286 return true; 287 288 // strategy: 289 // Check for full match first. Then work our way up the 290 // name looking for matches on a.b.* 291 292 String pname = p.getName(); 293 294 Permission x = (Permission) permissions.get(pname); 295 296 if (x != null) 297 // we have a direct hit! 298 return x.implies(permission); 299 300 301 // work our way up the tree... 302 int last, offset; 303 304 offset = pname.length() - 1; 305 306 while ((last = pname.lastIndexOf(".", offset)) != -1) { 307 308 pname = pname.substring(0, last+1) + "*"; 309 x = (Permission) permissions.get(pname); 310 311 if (x != null) { 312 return x.implies(permission); 313 } 314 offset = last - 1; 315 } 316 317 // check for "=*" wildcard match 318 pname = p.getName(); 319 offset = pname.length() - 1; 320 321 while ((last = pname.lastIndexOf("=", offset)) != -1) { 322 323 pname = pname.substring(0, last+1) + "*"; 324 x = (Permission) permissions.get(pname); 325 326 if (x != null) { 327 return x.implies(permission); 328 } 329 offset = last - 1; 330 } 331 332 // we don't have to check for "*" as it was already checked 333 // at the top (all_allowed), so we just return false 334 return false; 335 } 336 337 /** 338 * Returns an enumeration of all the ExecOptionPermission objects in the 339 * container. 340 * 341 * @return an enumeration of all the ExecOptionPermission objects. 342 */ 343 344 public Enumeration elements() 345 { 346 return permissions.elements(); 347 } 348 } 349 }