1 /* 2 * Copyright (c) 2000, 2020, 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 * 36 * @author Ann Wollrath 37 * 38 * @serial exclude 39 * @deprecated See the 40 * <a href="{@docRoot}/java.rmi/java/rmi/activation/package-summary.html"> 41 * {@code java.rmi.activation}</a> package specification for further information. 42 */ 43 @Deprecated(forRemoval=true, since="15") 44 public final class ExecOptionPermission extends Permission 45 { 46 /** 47 * does this permission have a wildcard at the end? 48 */ 49 private transient boolean wildcard; 50 51 /** 52 * the name without the wildcard on the end 53 */ 54 private transient String name; 55 56 /** 57 * UID for serialization 58 */ 59 private static final long serialVersionUID = 5842294756823092756L; 60 ExecOptionPermission(String name)61 public ExecOptionPermission(String name) { 62 super(name); 63 init(name); 64 } 65 ExecOptionPermission(String name, String actions)66 public ExecOptionPermission(String name, String actions) { 67 this(name); 68 } 69 70 /** 71 * Checks if the specified permission is "implied" by 72 * this object. 73 * <P> 74 * More specifically, this method returns true if: 75 * <ul> 76 * <li> <i>p</i>'s class is the same as this object's class, and 77 * <li> <i>p</i>'s name equals or (in the case of wildcards) 78 * is implied by this object's 79 * name. For example, "a.b.*" implies "a.b.c", and 80 * "a.b=*" implies "a.b=c" 81 * </ul> 82 * 83 * @param p the permission to check against. 84 * 85 * @return true if the passed permission is equal to or 86 * implied by this permission, false otherwise. 87 */ implies(Permission p)88 public boolean implies(Permission p) { 89 if (!(p instanceof ExecOptionPermission)) 90 return false; 91 92 ExecOptionPermission that = (ExecOptionPermission) p; 93 94 if (this.wildcard) { 95 if (that.wildcard) { 96 // one wildcard can imply another 97 return that.name.startsWith(name); 98 } else { 99 // make sure p.name is longer so a.b.* doesn't imply a.b 100 return (that.name.length() > this.name.length()) && 101 that.name.startsWith(this.name); 102 } 103 } else { 104 if (that.wildcard) { 105 // a non-wildcard can't imply a wildcard 106 return false; 107 } else { 108 return this.name.equals(that.name); 109 } 110 } 111 } 112 113 /** 114 * Checks two ExecOptionPermission objects for equality. 115 * Checks that <i>obj</i>'s class is the same as this object's class 116 * and has the same name as this object. 117 * 118 * @param obj the object we are testing for equality with this object. 119 * @return true if <i>obj</i> is an ExecOptionPermission, and has the same 120 * name as this ExecOptionPermission object, false otherwise. 121 */ equals(Object obj)122 public boolean equals(Object obj) { 123 if (obj == this) 124 return true; 125 126 if ((obj == null) || (obj.getClass() != getClass())) 127 return false; 128 129 ExecOptionPermission that = (ExecOptionPermission) obj; 130 131 return this.getName().equals(that.getName()); 132 } 133 134 135 /** 136 * Returns the hash code value for this object. 137 * The hash code used is the hash code of the name, that is, 138 * <code>getName().hashCode()</code>, where <code>getName</code> is 139 * from the Permission superclass. 140 * 141 * @return a hash code value for this object. 142 */ hashCode()143 public int hashCode() { 144 return this.getName().hashCode(); 145 } 146 147 /** 148 * Returns the canonical string representation of the actions. 149 * 150 * @return the canonical string representation of the actions. 151 */ getActions()152 public String getActions() { 153 return ""; 154 } 155 156 /** 157 * Returns a new PermissionCollection object for storing 158 * ExecOptionPermission objects. 159 * <p> 160 * An ExecOptionPermissionCollection stores a collection of 161 * ExecOptionPermission permissions. 162 * 163 * <p>ExecOptionPermission objects must be stored in a manner that allows 164 * them to be inserted in any order, but that also enables the 165 * PermissionCollection <code>implies</code> method 166 * to be implemented in an efficient (and consistent) manner. 167 * 168 * @return a new PermissionCollection object suitable for 169 * storing ExecOptionPermissions. 170 */ newPermissionCollection()171 public PermissionCollection newPermissionCollection() { 172 return new ExecOptionPermissionCollection(); 173 } 174 175 /** 176 * readObject is called to restore the state of the ExecOptionPermission 177 * from a stream. 178 */ readObject(java.io.ObjectInputStream s)179 private synchronized void readObject(java.io.ObjectInputStream s) 180 throws IOException, ClassNotFoundException 181 { 182 s.defaultReadObject(); 183 // init is called to initialize the rest of the values. 184 init(getName()); 185 } 186 187 /** 188 * Initialize a ExecOptionPermission object. Common to all constructors. 189 * Also called during de-serialization. 190 */ init(String name)191 private void init(String name) 192 { 193 if (name == null) 194 throw new NullPointerException("name can't be null"); 195 196 if (name.isEmpty()) { 197 throw new IllegalArgumentException("name can't be empty"); 198 } 199 200 if (name.endsWith(".*") || name.endsWith("=*") || name.equals("*")) { 201 wildcard = true; 202 if (name.length() == 1) { 203 this.name = ""; 204 } else { 205 this.name = name.substring(0, name.length()-1); 206 } 207 } else { 208 this.name = name; 209 } 210 } 211 212 /** 213 * A ExecOptionPermissionCollection stores a collection 214 * of ExecOptionPermission permissions. ExecOptionPermission objects 215 * must be stored in a manner that allows them to be inserted in any 216 * order, but enable the implies function to evaluate the implies 217 * method in an efficient (and consistent) manner. 218 * 219 * A ExecOptionPermissionCollection handles comparing a permission like 220 * "a.b.c.d.e" * with a Permission such as "a.b.*", or "*". 221 * 222 * @serial include 223 */ 224 private static class ExecOptionPermissionCollection 225 extends PermissionCollection 226 implements java.io.Serializable 227 { 228 229 private Hashtable<String, Permission> permissions; 230 private boolean all_allowed; // true if "*" is in the collection 231 private static final long serialVersionUID = -1242475729790124375L; 232 233 /** 234 * Create an empty ExecOptionPermissionCollection. 235 */ ExecOptionPermissionCollection()236 public ExecOptionPermissionCollection() { 237 permissions = new Hashtable<>(11); 238 all_allowed = false; 239 } 240 241 /** 242 * Adds a permission to the collection. The key for the hash is 243 * permission.name. 244 * 245 * @param permission the Permission object to add. 246 * 247 * @exception IllegalArgumentException - if the permission is not a 248 * ExecOptionPermission 249 * 250 * @exception SecurityException - if this ExecOptionPermissionCollection 251 * object has been marked readonly 252 */ 253 add(Permission permission)254 public void add(Permission permission) 255 { 256 if (! (permission instanceof ExecOptionPermission)) 257 throw new IllegalArgumentException("invalid permission: "+ 258 permission); 259 if (isReadOnly()) 260 throw new SecurityException("attempt to add a Permission to a readonly PermissionCollection"); 261 262 ExecOptionPermission p = (ExecOptionPermission) permission; 263 264 permissions.put(p.getName(), permission); 265 if (!all_allowed) { 266 if (p.getName().equals("*")) 267 all_allowed = true; 268 } 269 } 270 271 /** 272 * Check and see if this set of permissions implies the permissions 273 * expressed in "permission". 274 * 275 * @param p the Permission object to compare 276 * 277 * @return true if "permission" is a proper subset of a permission in 278 * the set, false if not. 279 */ implies(Permission permission)280 public boolean implies(Permission permission) 281 { 282 if (! (permission instanceof ExecOptionPermission)) 283 return false; 284 285 ExecOptionPermission p = (ExecOptionPermission) permission; 286 287 // short circuit if the "*" Permission was added 288 if (all_allowed) 289 return true; 290 291 // strategy: 292 // Check for full match first. Then work our way up the 293 // name looking for matches on a.b.* 294 295 String pname = p.getName(); 296 297 Permission x = permissions.get(pname); 298 299 if (x != null) 300 // we have a direct hit! 301 return x.implies(permission); 302 303 304 // work our way up the tree... 305 int last, offset; 306 307 offset = pname.length() - 1; 308 309 while ((last = pname.lastIndexOf('.', offset)) != -1) { 310 311 pname = pname.substring(0, last+1) + "*"; 312 x = permissions.get(pname); 313 314 if (x != null) { 315 return x.implies(permission); 316 } 317 offset = last - 1; 318 } 319 320 // check for "=*" wildcard match 321 pname = p.getName(); 322 offset = pname.length() - 1; 323 324 while ((last = pname.lastIndexOf('=', offset)) != -1) { 325 326 pname = pname.substring(0, last+1) + "*"; 327 x = permissions.get(pname); 328 329 if (x != null) { 330 return x.implies(permission); 331 } 332 offset = last - 1; 333 } 334 335 // we don't have to check for "*" as it was already checked 336 // at the top (all_allowed), so we just return false 337 return false; 338 } 339 340 /** 341 * Returns an enumeration of all the ExecOptionPermission objects in the 342 * container. 343 * 344 * @return an enumeration of all the ExecOptionPermission objects. 345 */ 346 elements()347 public Enumeration<Permission> elements() 348 { 349 return permissions.elements(); 350 } 351 } 352 } 353