Source Code Cross Referenced for ServicePermission.java in  » 6.0-JDK-Core » security » javax » security » auth » kerberos » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Home
Java Source Code / Java Documentation
1.6.0 JDK Core
2.6.0 JDK Modules
3.6.0 JDK Modules com.sun
4.6.0 JDK Modules com.sun.java
5.6.0 JDK Modules sun
6.6.0 JDK Platform
7.Ajax
8.Apache Harmony Java SE
9.Aspect oriented
10.Authentication Authorization
11.Blogger System
12.Build
13.Byte Code
14.Cache
15.Chart
16.Chat
17.Code Analyzer
18.Collaboration
19.Content Management System
20.Database Client
21.Database DBMS
22.Database JDBC Connection Pool
23.Database ORM
24.Development
25.EJB Server
26.ERP CRM Financial
27.ESB
28.Forum
29.Game
30.GIS
31.Graphic 3D
32.Graphic Library
33.Groupware
34.HTML Parser
35.IDE
36.IDE Eclipse
37.IDE Netbeans
38.Installer
39.Internationalization Localization
40.Inversion of Control
41.Issue Tracking
42.J2EE
43.J2ME
44.JBoss
45.JMS
46.JMX
47.Library
48.Mail Clients
49.Music
50.Net
51.Parser
52.PDF
53.Portal
54.Profiler
55.Project Management
56.Report
57.RSS RDF
58.Rule Engine
59.Science
60.Scripting
61.Search Engine
62.Security
63.Sevlet Container
64.Source Control
65.Swing Library
66.Template Engine
67.Test Coverage
68.Testing
69.UML
70.Web Crawler
71.Web Framework
72.Web Mail
73.Web Server
74.Web Services
75.Web Services apache cxf 2.2.6
76.Web Services AXIS2
77.Wiki Engine
78.Workflow Engines
79.XML
80.XML UI
Java Source Code / Java Documentation » 6.0 JDK Core » security » javax.security.auth.kerberos 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001        /*
002         * Copyright 2000-2006 Sun Microsystems, Inc.  All Rights Reserved.
003         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004         *
005         * This code is free software; you can redistribute it and/or modify it
006         * under the terms of the GNU General Public License version 2 only, as
007         * published by the Free Software Foundation.  Sun designates this
008         * particular file as subject to the "Classpath" exception as provided
009         * by Sun in the LICENSE file that accompanied this code.
010         *
011         * This code is distributed in the hope that it will be useful, but WITHOUT
012         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
014         * version 2 for more details (a copy is included in the LICENSE file that
015         * accompanied this code).
016         *
017         * You should have received a copy of the GNU General Public License version
018         * 2 along with this work; if not, write to the Free Software Foundation,
019         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020         *
021         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022         * CA 95054 USA or visit www.sun.com if you need additional information or
023         * have any questions.
024         */
025
026        package javax.security.auth.kerberos;
027
028        import java.util.*;
029        import java.security.Permission;
030        import java.security.PermissionCollection;
031        import java.io.ObjectStreamField;
032        import java.io.ObjectOutputStream;
033        import java.io.ObjectInputStream;
034        import java.io.IOException;
035
036        /**
037         * This class is used to protect Kerberos services and the 
038         * credentials necessary to access those services. There is a one to 
039         * one mapping of a service principal and the credentials necessary
040         * to access the service. Therefore granting access to a service
041         * principal implicitly grants access to the credential necessary to
042         * establish a security context with the service principal. This
043         * applies regardless of whether the credentials are in a cache
044         * or acquired via an exchange with the KDC. The credential can
045         * be either a ticket granting ticket, a service ticket or a secret
046         * key from a key table.
047         * <p>
048         * A ServicePermission contains a service principal name and
049         * a list of actions which specify the context the credential can be
050         * used within.
051         * <p>
052         * The service principal name is the canonical name of the
053         * <code>KereberosPrincipal</code> supplying the service, that is
054         * the KerberosPrincipal represents a Kerberos service
055         * principal. This name is treated in a case sensitive manner.
056         * An asterisk may appear by itself, to signify any service principal.
057         * <p>
058         * Granting this permission implies that the caller can use a cached
059         * credential (TGT, service ticket or secret key) within the context
060         * designated by the action. In the case of the TGT, granting this
061         * permission also implies that the TGT can be obtained by an
062         * Authentication Service exchange.
063         * <p>
064         * The possible actions are:
065         * <p>
066         * <pre>
067         *    initiate -              allow the caller to use the credential to
068         *                            initiate a security context with a service
069         *                            principal.
070         *
071         *    accept -                allow the caller to use the credential to
072         *                            accept security context as a particular
073         *                            principal.
074         * </pre>
075         *
076         * For example, to specify the permission to access to the TGT to
077         * initiate a security context the permission is constructed as follows:
078         * <p>
079         * <pre>
080         *     ServicePermission("krbtgt/EXAMPLE.COM@EXAMPLE.COM", "initiate");
081         * </pre>
082         * <p>
083         * To obtain a service ticket to initiate a context with the "host"
084         * service the permission is constructed as follows:
085         * <pre>
086         *     ServicePermission("host/foo.example.com@EXAMPLE.COM", "initiate");
087         * </pre>
088         * <p>
089         * For a Kerberized server the action is "accept". For example, the permission
090         * necessary to access and use the secret key of the  Kerberized "host"
091         * service (telnet and the likes)  would be constructed as follows:
092         * <p>
093         * <pre>
094         *     ServicePermission("host/foo.example.com@EXAMPLE.COM", "accept");
095         * </pre>
096         * 
097         * @since 1.4
098         */
099
100        public final class ServicePermission extends Permission implements 
101                java.io.Serializable {
102
103            private static final long serialVersionUID = -1227585031618624935L;
104
105            /**
106             * Initiate a security context to the specified service
107             */
108            private final static int INITIATE = 0x1;
109
110            /**
111             * Accept a security context
112             */
113            private final static int ACCEPT = 0x2;
114
115            /**
116             * All actions
117             */
118            private final static int ALL = INITIATE | ACCEPT;
119
120            /**
121             * No actions.
122             */
123            private final static int NONE = 0x0;
124
125            // the actions mask
126            private transient int mask;
127
128            /**
129             * the actions string. 
130             *
131             * @serial
132             */
133
134            private String actions; // Left null as long as possible, then
135
136            // created and re-used in the getAction function.
137
138            /**
139             * Create a new <code>ServicePermission</code>
140             * with the specified <code>servicePrincipal</code>
141             * and <code>action</code>.
142             *
143             * @param servicePrincipal the name of the service principal.
144             * An asterisk may appear by itself, to signify any service principal.
145             * <p>
146             * @param action the action string
147             */
148            public ServicePermission(String servicePrincipal, String action) {
149                super (servicePrincipal);
150                init(servicePrincipal, getMask(action));
151            }
152
153            /**
154             * Initialize the ServicePermission object.
155             */
156            private void init(String servicePrincipal, int mask) {
157
158                if (servicePrincipal == null)
159                    throw new NullPointerException(
160                            "service principal can't be null");
161
162                if ((mask & ALL) != mask)
163                    throw new IllegalArgumentException("invalid actions mask");
164
165                this .mask = mask;
166            }
167
168            /**
169             * Checks if this Kerberos service permission object "implies" the 
170             * specified permission.
171             * <P>
172             * If none of the above are true, <code>implies</code> returns false.
173             * @param p the permission to check against.
174             *
175             * @return true if the specified permission is implied by this object,
176             * false if not.  
177             */
178            public boolean implies(Permission p) {
179                if (!(p instanceof  ServicePermission))
180                    return false;
181
182                ServicePermission that = (ServicePermission) p;
183
184                return ((this .mask & that.mask) == that.mask)
185                        && impliesIgnoreMask(that);
186            }
187
188            boolean impliesIgnoreMask(ServicePermission p) {
189                return ((this .getName().equals("*")) || this .getName().equals(
190                        p.getName()));
191            }
192
193            /**
194             * Checks two ServicePermission objects for equality. 
195             * <P>
196             * @param obj the object to test for equality with this object.
197             * 
198             * @return true if <i>obj</i> is a ServicePermission, and has the
199             *  same service principal, and actions as this
200             * ServicePermission object.
201             */
202            public boolean equals(Object obj) {
203                if (obj == this )
204                    return true;
205
206                if (!(obj instanceof  ServicePermission))
207                    return false;
208
209                ServicePermission that = (ServicePermission) obj;
210                return ((this .mask & that.mask) == that.mask)
211                        && this .getName().equals(that.getName());
212
213            }
214
215            /**
216             * Returns the hash code value for this object.
217             *
218             * @return a hash code value for this object.
219             */
220
221            public int hashCode() {
222                return (getName().hashCode() ^ mask);
223            }
224
225            /**
226             * Returns the "canonical string representation" of the actions in the
227             * specified mask.
228             * Always returns present actions in the following order: 
229             * initiate, accept.
230             *
231             * @param mask a specific integer action mask to translate into a string
232             * @return the canonical string representation of the actions
233             */
234            private static String getActions(int mask) {
235                StringBuilder sb = new StringBuilder();
236                boolean comma = false;
237
238                if ((mask & INITIATE) == INITIATE) {
239                    if (comma)
240                        sb.append(',');
241                    else
242                        comma = true;
243                    sb.append("initiate");
244                }
245
246                if ((mask & ACCEPT) == ACCEPT) {
247                    if (comma)
248                        sb.append(',');
249                    else
250                        comma = true;
251                    sb.append("accept");
252                }
253
254                return sb.toString();
255            }
256
257            /**
258             * Returns the canonical string representation of the actions.
259             * Always returns present actions in the following order:
260             * initiate, accept.
261             */
262
263            public String getActions() {
264                if (actions == null)
265                    actions = getActions(this .mask);
266
267                return actions;
268            }
269
270            /**
271             * Returns a PermissionCollection object for storing
272             * ServicePermission objects.
273             * <br>
274             * ServicePermission objects must be stored in a manner that
275             * allows them to be inserted into the collection in any order, but
276             * that also enables the PermissionCollection implies method to
277             * be implemented in an efficient (and consistent) manner.
278             *
279             * @return a new PermissionCollection object suitable for storing
280             * ServicePermissions.
281             */
282
283            public PermissionCollection newPermissionCollection() {
284                return new KrbServicePermissionCollection();
285            }
286
287            /**
288             * Return the current action mask.
289             *
290             * @return the actions mask.
291             */
292
293            int getMask() {
294                return mask;
295            }
296
297            /**
298             * Convert an action string to an integer actions mask. 
299             *
300             * @param action the action string
301             * @return the action mask
302             */
303
304            private static int getMask(String action) {
305
306                if (action == null) {
307                    throw new NullPointerException("action can't be null");
308                }
309
310                if (action.equals("")) {
311                    throw new IllegalArgumentException("action can't be empty");
312                }
313
314                int mask = NONE;
315
316                char[] a = action.toCharArray();
317
318                int i = a.length - 1;
319                if (i < 0)
320                    return mask;
321
322                while (i != -1) {
323                    char c;
324
325                    // skip whitespace
326                    while ((i != -1)
327                            && ((c = a[i]) == ' ' || c == '\r' || c == '\n'
328                                    || c == '\f' || c == '\t'))
329                        i--;
330
331                    // check for the known strings
332                    int matchlen;
333
334                    if (i >= 7 && (a[i - 7] == 'i' || a[i - 7] == 'I')
335                            && (a[i - 6] == 'n' || a[i - 6] == 'N')
336                            && (a[i - 5] == 'i' || a[i - 5] == 'I')
337                            && (a[i - 4] == 't' || a[i - 4] == 'T')
338                            && (a[i - 3] == 'i' || a[i - 3] == 'I')
339                            && (a[i - 2] == 'a' || a[i - 2] == 'A')
340                            && (a[i - 1] == 't' || a[i - 1] == 'T')
341                            && (a[i] == 'e' || a[i] == 'E')) {
342                        matchlen = 8;
343                        mask |= INITIATE;
344
345                    } else if (i >= 5 && (a[i - 5] == 'a' || a[i - 5] == 'A')
346                            && (a[i - 4] == 'c' || a[i - 4] == 'C')
347                            && (a[i - 3] == 'c' || a[i - 3] == 'C')
348                            && (a[i - 2] == 'e' || a[i - 2] == 'E')
349                            && (a[i - 1] == 'p' || a[i - 1] == 'P')
350                            && (a[i] == 't' || a[i] == 'T')) {
351                        matchlen = 6;
352                        mask |= ACCEPT;
353
354                    } else {
355                        // parse error
356                        throw new IllegalArgumentException(
357                                "invalid permission: " + action);
358                    }
359
360                    // make sure we didn't just match the tail of a word
361                    // like "ackbarfaccept".  Also, skip to the comma.
362                    boolean seencomma = false;
363                    while (i >= matchlen && !seencomma) {
364                        switch (a[i - matchlen]) {
365                        case ',':
366                            seencomma = true;
367                            /*FALLTHROUGH*/
368                        case ' ':
369                        case '\r':
370                        case '\n':
371                        case '\f':
372                        case '\t':
373                            break;
374                        default:
375                            throw new IllegalArgumentException(
376                                    "invalid permission: " + action);
377                        }
378                        i--;
379                    }
380
381                    // point i at the location of the comma minus one (or -1).
382                    i -= matchlen;
383                }
384
385                return mask;
386            }
387
388            /**
389             * WriteObject is called to save the state of the ServicePermission 
390             * to a stream. The actions are serialized, and the superclass
391             * takes care of the name.
392             */
393            private void writeObject(java.io.ObjectOutputStream s)
394                    throws IOException {
395                // Write out the actions. The superclass takes care of the name
396                // call getActions to make sure actions field is initialized
397                if (actions == null)
398                    getActions();
399                s.defaultWriteObject();
400            }
401
402            /**
403             * readObject is called to restore the state of the
404             * ServicePermission from a stream.
405             */
406            private void readObject(java.io.ObjectInputStream s)
407                    throws IOException, ClassNotFoundException {
408                // Read in the action, then initialize the rest
409                s.defaultReadObject();
410                init(getName(), getMask(actions));
411            }
412
413            /*
414              public static void main(String args[]) throws Exception {
415              ServicePermission this_ =
416              new ServicePermission(args[0], "accept");
417              ServicePermission that_ =
418              new ServicePermission(args[1], "accept,initiate");
419              System.out.println("-----\n");
420              System.out.println("this.implies(that) = " + this_.implies(that_));
421              System.out.println("-----\n");
422              System.out.println("this = "+this_);
423              System.out.println("-----\n");
424              System.out.println("that = "+that_);
425              System.out.println("-----\n");
426
427              KrbServicePermissionCollection nps =
428              new KrbServicePermissionCollection();
429              nps.add(this_);
430              nps.add(new ServicePermission("nfs/example.com@EXAMPLE.COM",
431              "accept"));
432              nps.add(new ServicePermission("host/example.com@EXAMPLE.COM",
433              "initiate"));
434              System.out.println("nps.implies(that) = " + nps.implies(that_));
435              System.out.println("-----\n");
436
437              Enumeration e = nps.elements();
438            
439              while (e.hasMoreElements()) {
440              ServicePermission x =
441              (ServicePermission) e.nextElement();
442              System.out.println("nps.e = " + x);
443              }
444
445              }
446             */
447
448        }
449
450        final class KrbServicePermissionCollection extends PermissionCollection
451                implements  java.io.Serializable {
452
453            // Not serialized; see serialization section at end of class
454            private transient List<Permission> perms;
455
456            public KrbServicePermissionCollection() {
457                perms = new ArrayList<Permission>();
458            }
459
460            /**
461             * Check and see if this collection of permissions implies the permissions 
462             * expressed in "permission".
463             *
464             * @param p the Permission object to compare
465             *
466             * @return true if "permission" is a proper subset of a permission in 
467             * the collection, false if not.
468             */
469
470            public boolean implies(Permission permission) {
471                if (!(permission instanceof  ServicePermission))
472                    return false;
473
474                ServicePermission np = (ServicePermission) permission;
475                int desired = np.getMask();
476                int effective = 0;
477                int needed = desired;
478
479                synchronized (this ) {
480                    int len = perms.size();
481
482                    // need to deal with the case where the needed permission has
483                    // more than one action and the collection has individual permissions
484                    // that sum up to the needed.
485
486                    for (int i = 0; i < len; i++) {
487                        ServicePermission x = (ServicePermission) perms.get(i);
488
489                        //System.out.println("  trying "+x);
490                        if (((needed & x.getMask()) != 0)
491                                && x.impliesIgnoreMask(np)) {
492                            effective |= x.getMask();
493                            if ((effective & desired) == desired)
494                                return true;
495                            needed = (desired ^ effective);
496                        }
497                    }
498                }
499                return false;
500            }
501
502            /**
503             * Adds a permission to the ServicePermissions. The key for
504             * the hash is the name.
505             *
506             * @param permission the Permission object to add.
507             *
508             * @exception IllegalArgumentException - if the permission is not a
509             *                                       ServicePermission
510             *
511             * @exception SecurityException - if this PermissionCollection object
512             *                                has been marked readonly
513             */
514
515            public void add(Permission permission) {
516                if (!(permission instanceof  ServicePermission))
517                    throw new IllegalArgumentException("invalid permission: "
518                            + permission);
519                if (isReadOnly())
520                    throw new SecurityException(
521                            "attempt to add a Permission to a readonly PermissionCollection");
522
523                synchronized (this ) {
524                    perms.add(0, permission);
525                }
526            }
527
528            /**
529             * Returns an enumeration of all the ServicePermission objects
530             * in the container.
531             *
532             * @return an enumeration of all the ServicePermission objects.
533             */
534
535            public Enumeration<Permission> elements() {
536                // Convert Iterator into Enumeration
537                synchronized (this ) {
538                    return Collections.enumeration(perms);
539                }
540            }
541
542            private static final long serialVersionUID = -4118834211490102011L;
543
544            // Need to maintain serialization interoperability with earlier releases,
545            // which had the serializable field:
546            // private Vector permissions;
547
548            /**
549             * @serialField permissions java.util.Vector
550             *     A list of ServicePermission objects.
551             */
552            private static final ObjectStreamField[] serialPersistentFields = { new ObjectStreamField(
553                    "permissions", Vector.class), };
554
555            /**
556             * @serialData "permissions" field (a Vector containing the ServicePermissions).
557             */
558            /*
559             * Writes the contents of the perms field out as a Vector for
560             * serialization compatibility with earlier releases.
561             */
562            private void writeObject(ObjectOutputStream out) throws IOException {
563                // Don't call out.defaultWriteObject()
564
565                // Write out Vector
566                Vector<Permission> permissions = new Vector<Permission>(perms
567                        .size());
568
569                synchronized (this ) {
570                    permissions.addAll(perms);
571                }
572
573                ObjectOutputStream.PutField pfields = out.putFields();
574                pfields.put("permissions", permissions);
575                out.writeFields();
576            }
577
578            /*
579             * Reads in a Vector of ServicePermissions and saves them in the perms field.
580             */
581            private void readObject(ObjectInputStream in) throws IOException,
582                    ClassNotFoundException {
583                // Don't call defaultReadObject()
584
585                // Read in serialized fields
586                ObjectInputStream.GetField gfields = in.readFields();
587
588                // Get the one we want
589                Vector<Permission> permissions = (Vector<Permission>) gfields
590                        .get("permissions", null);
591                perms = new ArrayList<Permission>(permissions.size());
592                perms.addAll(permissions);
593            }
594        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.