Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/javax/security/auth/kerberos/DelegationPermission.java
38918 views
/*1* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package javax.security.auth.kerberos;2627import java.util.*;28import java.security.Permission;29import java.security.BasicPermission;30import java.security.PermissionCollection;31import java.io.ObjectStreamField;32import java.io.ObjectOutputStream;33import java.io.ObjectInputStream;34import java.io.IOException;3536/**37* This class is used to restrict the usage of the Kerberos38* delegation model, ie: forwardable and proxiable tickets.39* <p>40* The target name of this {@code Permission} specifies a pair of41* kerberos service principals. The first is the subordinate service principal42* being entrusted to use the TGT. The second service principal designates43* the target service the subordinate service principal is to44* interact with on behalf of the initiating KerberosPrincipal. This45* latter service principal is specified to restrict the use of a46* proxiable ticket.47* <p>48* For example, to specify the "host" service use of a forwardable TGT the49* target permission is specified as follows:50*51* <pre>52* DelegationPermission("\"host/[email protected]\" \"krbtgt/[email protected]\"");53* </pre>54* <p>55* To give the "backup" service a proxiable nfs service ticket the target permission56* might be specified:57*58* <pre>59* DelegationPermission("\"backup/[email protected]\" \"nfs/[email protected]\"");60* </pre>61*62* @since 1.463*/6465public final class DelegationPermission extends BasicPermission66implements java.io.Serializable {6768private static final long serialVersionUID = 883133252142523922L;6970private transient String subordinate, service;7172/**73* Create a new {@code DelegationPermission}74* with the specified subordinate and target principals.75*76* <p>77*78* @param principals the name of the subordinate and target principals79*80* @throws NullPointerException if {@code principals} is {@code null}.81* @throws IllegalArgumentException if {@code principals} is empty.82*/83public DelegationPermission(String principals) {84super(principals);85init(principals);86}8788/**89* Create a new {@code DelegationPermission}90* with the specified subordinate and target principals.91* <p>92*93* @param principals the name of the subordinate and target principals94* <p>95* @param actions should be null.96*97* @throws NullPointerException if {@code principals} is {@code null}.98* @throws IllegalArgumentException if {@code principals} is empty.99*/100public DelegationPermission(String principals, String actions) {101super(principals, actions);102init(principals);103}104105106/**107* Initialize the DelegationPermission object.108*/109private void init(String target) {110111StringTokenizer t = null;112if (!target.startsWith("\"")) {113throw new IllegalArgumentException114("service principal [" + target +115"] syntax invalid: " +116"improperly quoted");117} else {118t = new StringTokenizer(target, "\"", false);119subordinate = t.nextToken();120if (t.countTokens() == 2) {121t.nextToken(); // bypass whitespace122service = t.nextToken();123} else if (t.countTokens() > 0) {124throw new IllegalArgumentException125("service principal [" + t.nextToken() +126"] syntax invalid: " +127"improperly quoted");128}129}130}131132/**133* Checks if this Kerberos delegation permission object "implies" the134* specified permission.135* <P>136* If none of the above are true, {@code implies} returns false.137* @param p the permission to check against.138*139* @return true if the specified permission is implied by this object,140* false if not.141*/142public boolean implies(Permission p) {143if (!(p instanceof DelegationPermission))144return false;145146DelegationPermission that = (DelegationPermission) p;147if (this.subordinate.equals(that.subordinate) &&148this.service.equals(that.service))149return true;150151return false;152}153154155/**156* Checks two DelegationPermission objects for equality.157* <P>158* @param obj the object to test for equality with this object.159*160* @return true if <i>obj</i> is a DelegationPermission, and161* has the same subordinate and service principal as this.162* DelegationPermission object.163*/164public boolean equals(Object obj) {165if (obj == this)166return true;167168if (! (obj instanceof DelegationPermission))169return false;170171DelegationPermission that = (DelegationPermission) obj;172return implies(that);173}174175/**176* Returns the hash code value for this object.177*178* @return a hash code value for this object.179*/180public int hashCode() {181return getName().hashCode();182}183184185/**186* Returns a PermissionCollection object for storing187* DelegationPermission objects.188* <br>189* DelegationPermission objects must be stored in a manner that190* allows them to be inserted into the collection in any order, but191* that also enables the PermissionCollection implies method to192* be implemented in an efficient (and consistent) manner.193*194* @return a new PermissionCollection object suitable for storing195* DelegationPermissions.196*/197198public PermissionCollection newPermissionCollection() {199return new KrbDelegationPermissionCollection();200}201202/**203* WriteObject is called to save the state of the DelegationPermission204* to a stream. The actions are serialized, and the superclass205* takes care of the name.206*/207private synchronized void writeObject(java.io.ObjectOutputStream s)208throws IOException209{210s.defaultWriteObject();211}212213/**214* readObject is called to restore the state of the215* DelegationPermission from a stream.216*/217private synchronized void readObject(java.io.ObjectInputStream s)218throws IOException, ClassNotFoundException219{220// Read in the action, then initialize the rest221s.defaultReadObject();222init(getName());223}224225/*226public static void main(String args[]) throws Exception {227DelegationPermission this_ =228new DelegationPermission(args[0]);229DelegationPermission that_ =230new DelegationPermission(args[1]);231System.out.println("-----\n");232System.out.println("this.implies(that) = " + this_.implies(that_));233System.out.println("-----\n");234System.out.println("this = "+this_);235System.out.println("-----\n");236System.out.println("that = "+that_);237System.out.println("-----\n");238239KrbDelegationPermissionCollection nps =240new KrbDelegationPermissionCollection();241nps.add(this_);242nps.add(new DelegationPermission("\"host/[email protected]\" \"CN=Gary Ellison/OU=JSN/O=SUNW/L=Palo Alto/ST=CA/C=US\""));243try {244nps.add(new DelegationPermission("host/[email protected] \"CN=Gary Ellison/OU=JSN/O=SUNW/L=Palo Alto/ST=CA/C=US\""));245} catch (Exception e) {246System.err.println(e);247}248249System.out.println("nps.implies(that) = " + nps.implies(that_));250System.out.println("-----\n");251252Enumeration e = nps.elements();253254while (e.hasMoreElements()) {255DelegationPermission x =256(DelegationPermission) e.nextElement();257System.out.println("nps.e = " + x);258}259}260*/261}262263264final class KrbDelegationPermissionCollection extends PermissionCollection265implements java.io.Serializable {266267// Not serialized; see serialization section at end of class.268private transient List<Permission> perms;269270public KrbDelegationPermissionCollection() {271perms = new ArrayList<Permission>();272}273274275/**276* Check and see if this collection of permissions implies the permissions277* expressed in "permission".278*279* @param permission the Permission object to compare280*281* @return true if "permission" is a proper subset of a permission in282* the collection, false if not.283*/284public boolean implies(Permission permission) {285if (! (permission instanceof DelegationPermission))286return false;287288synchronized (this) {289for (Permission x : perms) {290if (x.implies(permission))291return true;292}293}294return false;295296}297298/**299* Adds a permission to the DelegationPermissions. The key for300* the hash is the name.301*302* @param permission the Permission object to add.303*304* @exception IllegalArgumentException - if the permission is not a305* DelegationPermission306*307* @exception SecurityException - if this PermissionCollection object308* has been marked readonly309*/310public void add(Permission permission) {311if (! (permission instanceof DelegationPermission))312throw new IllegalArgumentException("invalid permission: "+313permission);314if (isReadOnly())315throw new SecurityException("attempt to add a Permission to a readonly PermissionCollection");316317synchronized (this) {318perms.add(0, permission);319}320}321322/**323* Returns an enumeration of all the DelegationPermission objects324* in the container.325*326* @return an enumeration of all the DelegationPermission objects.327*/328public Enumeration<Permission> elements() {329// Convert Iterator into Enumeration330synchronized (this) {331return Collections.enumeration(perms);332}333}334335private static final long serialVersionUID = -3383936936589966948L;336337// Need to maintain serialization interoperability with earlier releases,338// which had the serializable field:339// private Vector permissions;340/**341* @serialField permissions java.util.Vector342* A list of DelegationPermission objects.343*/344private static final ObjectStreamField[] serialPersistentFields = {345new ObjectStreamField("permissions", Vector.class),346};347348/**349* @serialData "permissions" field (a Vector containing the DelegationPermissions).350*/351/*352* Writes the contents of the perms field out as a Vector for353* serialization compatibility with earlier releases.354*/355private void writeObject(ObjectOutputStream out) throws IOException {356// Don't call out.defaultWriteObject()357358// Write out Vector359Vector<Permission> permissions = new Vector<>(perms.size());360361synchronized (this) {362permissions.addAll(perms);363}364365ObjectOutputStream.PutField pfields = out.putFields();366pfields.put("permissions", permissions);367out.writeFields();368}369370/*371* Reads in a Vector of DelegationPermissions and saves them in the perms field.372*/373@SuppressWarnings("unchecked")374private void readObject(ObjectInputStream in)375throws IOException, ClassNotFoundException376{377// Don't call defaultReadObject()378379// Read in serialized fields380ObjectInputStream.GetField gfields = in.readFields();381382// Get the one we want383Vector<Permission> permissions =384(Vector<Permission>)gfields.get("permissions", null);385perms = new ArrayList<Permission>(permissions.size());386perms.addAll(permissions);387}388}389390391