Source Code Cross Referenced for ProviderList.java in  » 6.0-JDK-Modules-sun » security » sun » security » jgss » Java Source Code / Java DocumentationJava Source Code and Java Documentation

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 geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » 6.0 JDK Modules sun » security » sun.security.jgss 
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 sun.security.jgss;
027:
028:        import java.lang.reflect.InvocationTargetException;
029:        import org.ietf.jgss.*;
030:        import java.security.AccessController;
031:        import java.security.AccessControlContext;
032:        import java.security.PrivilegedAction;
033:        import java.security.Provider;
034:        import java.security.Security;
035:        import java.util.ArrayList;
036:        import java.util.HashSet;
037:        import java.util.HashMap;
038:        import java.util.Enumeration;
039:        import java.util.Iterator;
040:        import javax.security.auth.Subject;
041:        import sun.security.jgss.spi.*;
042:        import sun.security.jgss.wrapper.NativeGSSFactory;
043:        import sun.security.jgss.wrapper.SunNativeProvider;
044:        import sun.security.action.GetPropertyAction;
045:
046:        /**
047:         * This class stores the list of providers that this
048:         * GSS-Implementation is configured to use. The GSSManagerImpl class
049:         * queries this class whenever it needs a mechanism's factory.<p>
050:         *
051:         * This class stores an ordered list of pairs of the form 
052:         * <provider, oid>. When it attempts to instantiate a mechanism
053:         * defined by oid o, it steps through the list looking for an entry
054:         * with oid=o, or with oid=null. (An entry with oid=null matches all
055:         * mechanisms.) When it finds such an entry, the corresponding
056:         * provider is approached for the mechanism's factory class.
057:         * At instantiation time this list in initialized to contain those
058:         * system wide providers that contain a property of the form
059:         * "GssApiMechanism.x.y.z..." where "x.y.z..." is a numeric object
060:         * identifier with numbers x, y, z, etc. Such a property is defined
061:         * to map to that provider's implementation of the MechanismFactory
062:         * interface for the mechanism x.y.z...
063:         * As and when a MechanismFactory is instantiated, it is
064:         * cached for future use. <p>
065:         *
066:         * An application can cause more providers to be added by means of
067:         * the addProviderAtFront and addProviderAtEnd methods on
068:         * GSSManager which get delegated to this class. The
069:         * addProviderAtFront method can also cause a change in the ordering
070:         * of the providers without adding any new providers, by causing a
071:         * provider to move up in a list. The method addProviderAtEnd can
072:         * only add providers at the end of the list if they are not already
073:         * in the list. The rationale is that an application will call 
074:         * addProviderAtFront when it wants a provider to be used in
075:         * preference over the default ones. And it will call
076:         * addProviderAtEnd when it wants a provider to be used in case
077:         * the system ones don't suffice.<p>
078:         *
079:         * If a mechanism's factory is being obtained from a provider as a
080:         * result of encountering a entryof the form <provider, oid> where
081:         * oid is non-null, then the assumption is that the application added 
082:         * this entry and it wants this mechanism to be obtained from this
083:         * provider. Thus is the provider does not actually contain the
084:         * requested mechanism, an exception will be thrown. However, if the
085:         * entry were of the form <provider, null>, then it is viewed more
086:         * liberally and is simply skipped over if the provider does not claim to
087:         * support the requested mechanism.
088:         */
089:
090:        public final class ProviderList {
091:
092:            private static final String PROV_PROP_PREFIX = "GssApiMechanism.";
093:            private static final int PROV_PROP_PREFIX_LEN = PROV_PROP_PREFIX
094:                    .length();
095:
096:            private static final String SPI_MECH_FACTORY_TYPE = "sun.security.jgss.spi.MechanismFactory";
097:
098:            // Undocumented property?
099:            private static final String DEFAULT_MECH_PROP = "sun.security.jgss.mechanism";
100:
101:            public static final Oid DEFAULT_MECH_OID;
102:
103:            static {
104:                /*
105:                 * Set the default mechanism. Kerberos v5 is the default
106:                 * mechanism unless it is overridden by a system property.
107:                 * with a valid OID value
108:                 */
109:                Oid defOid = null;
110:                String defaultOidStr = AccessController
111:                        .doPrivileged(new GetPropertyAction(DEFAULT_MECH_PROP));
112:                if (defaultOidStr != null) {
113:                    defOid = GSSUtil.createOid(defaultOidStr);
114:                }
115:                DEFAULT_MECH_OID = (defOid == null ? GSSUtil.GSS_KRB5_MECH_OID
116:                        : defOid);
117:            }
118:
119:            private ArrayList<PreferencesEntry> preferences = new ArrayList<PreferencesEntry>(
120:                    5);
121:            private HashMap<PreferencesEntry, MechanismFactory> factories = new HashMap<PreferencesEntry, MechanismFactory>(
122:                    5);
123:            private HashSet<Oid> mechs = new HashSet<Oid>(5);
124:
125:            final private int caller;
126:
127:            public ProviderList(int caller, boolean useNative) {
128:                this .caller = caller;
129:                Provider[] provList;
130:                if (useNative) {
131:                    provList = new Provider[1];
132:                    provList[0] = new SunNativeProvider();
133:                } else {
134:                    provList = Security.getProviders();
135:                }
136:
137:                for (int i = 0; i < provList.length; i++) {
138:                    Provider prov = provList[i];
139:                    try {
140:                        addProviderAtEnd(prov, null);
141:                    } catch (GSSException ge) {
142:                        // Move on to the next provider
143:                        GSSUtil.debug("Error in adding provider "
144:                                + prov.getName() + ": " + ge);
145:                    }
146:                } // End of for loop
147:            }
148:
149:            /**
150:             * Determines if the given provider property represents a GSS-API
151:             * Oid to MechanismFactory mapping.
152:             * @return true if this is a GSS-API property, false otherwise.
153:             */
154:            private boolean isMechFactoryProperty(String prop) {
155:                return (prop.startsWith(PROV_PROP_PREFIX) || prop
156:                        .regionMatches(true, 0, // Try ignoring case
157:                                PROV_PROP_PREFIX, 0, PROV_PROP_PREFIX_LEN));
158:            }
159:
160:            private Oid getOidFromMechFactoryProperty(String prop)
161:                    throws GSSException {
162:
163:                String oidPart = prop.substring(PROV_PROP_PREFIX_LEN);
164:                return new Oid(oidPart);
165:            }
166:
167:            // So the existing code do not have to be changed
168:            synchronized public MechanismFactory getMechFactory(Oid mechOid)
169:                    throws GSSException {
170:                if (mechOid == null)
171:                    mechOid = ProviderList.DEFAULT_MECH_OID;
172:                return getMechFactory(mechOid, null);
173:            }
174:
175:            /**
176:             * Obtains a MechanismFactory for a given mechanism. If the
177:             * specified provider is not null, then the impl from the
178:             * provider is used. Otherwise, the most preferred impl based
179:             * on the configured preferences is used.
180:             * @param mechOid the oid of the desired mechanism
181:             * @return a MechanismFactory for the desired mechanism.
182:             * @throws GSSException when the specified provider does not
183:             * support the desired mechanism, or when no provider supports
184:             * the desired mechanism.
185:             */
186:            synchronized public MechanismFactory getMechFactory(Oid mechOid,
187:                    Provider p) throws GSSException {
188:
189:                if (mechOid == null)
190:                    mechOid = ProviderList.DEFAULT_MECH_OID;
191:
192:                if (p == null) {
193:                    // Iterate thru all preferences to find right provider
194:                    String className;
195:                    PreferencesEntry entry;
196:
197:                    Iterator<PreferencesEntry> list = preferences.iterator();
198:                    while (list.hasNext()) {
199:                        entry = list.next();
200:                        if (entry.impliesMechanism(mechOid)) {
201:                            MechanismFactory retVal = getMechFactory(entry,
202:                                    mechOid);
203:                            if (retVal != null)
204:                                return retVal;
205:                        }
206:                    } // end of while loop
207:                    throw new GSSExceptionImpl(GSSException.BAD_MECH, mechOid);
208:                } else {
209:                    // Use the impl from the specified provider; return null if the
210:                    // the mech is unsupported by the specified provider.
211:                    PreferencesEntry entry = new PreferencesEntry(p, mechOid);
212:                    return getMechFactory(entry, mechOid);
213:                }
214:            }
215:
216:            /**
217:             * Helper routine that uses a preferences entry to obtain an
218:             * implementation of a MechanismFactory from it.
219:             * @param e the preferences entry that contains the provider and
220:             * either a null of an explicit oid that matched the oid of the
221:             * desired mechanism.
222:             * @param mechOid the oid of the desired mechanism
223:             * @throws GSSException If the application explicitly requested
224:             * this entry's provider to be used for the desired mechanism but 
225:             * some problem is encountered
226:             */
227:            private MechanismFactory getMechFactory(PreferencesEntry e,
228:                    Oid mechOid) throws GSSException {
229:                Provider p = e.getProvider();
230:
231:                /*
232:                 * See if a MechanismFactory was previously instantiated for
233:                 * this provider and mechanism combination.
234:                 */
235:                PreferencesEntry searchEntry = new PreferencesEntry(p, mechOid);
236:                MechanismFactory retVal = factories.get(searchEntry);
237:                if (retVal == null) {
238:                    /*
239:                     * Apparently not. Now try to instantiate this class from
240:                     * the provider.
241:                     */
242:                    String prop = PROV_PROP_PREFIX + mechOid.toString();
243:                    String className = p.getProperty(prop);
244:                    if (className != null) {
245:                        retVal = getMechFactoryImpl(p, className, mechOid,
246:                                caller);
247:                        factories.put(searchEntry, retVal);
248:                    } else {
249:                        /*
250:                         * This provider does not support this mechanism.
251:                         * If the application explicitly requested that
252:                         * this provider be used for this mechanism, then
253:                         * throw an exception
254:                         */
255:                        if (e.getOid() != null) {
256:                            throw new GSSExceptionImpl(GSSException.BAD_MECH,
257:                                    "Provider " + p.getName()
258:                                            + " does not support mechanism "
259:                                            + mechOid);
260:                        }
261:                    }
262:                }
263:                return retVal;
264:            }
265:
266:            /**
267:             * Helper routine to obtain a MechanismFactory implementation
268:             * from the same class loader as the provider of this
269:             * implementation.
270:             * @param p the provider whose classloader must be used for
271:             * instantiating the desired MechanismFactory
272:             * @ param className the name of the MechanismFactory class
273:             * @throws GSSException If some error occurs when trying to
274:             * instantiate this MechanismFactory.
275:             */
276:            private static MechanismFactory getMechFactoryImpl(Provider p,
277:                    String className, Oid mechOid, int caller)
278:                    throws GSSException {
279:
280:                try {
281:                    Class<?> baseClass = Class.forName(SPI_MECH_FACTORY_TYPE);
282:
283:                    /*  
284:                     * Load the implementation class with the same class loader
285:                     * that was used to load the provider.
286:                     * In order to get the class loader of a class, the
287:                     * caller's class loader must be the same as or an ancestor of
288:                     * the class loader being returned. Otherwise, the caller must
289:                     * have "getClassLoader" permission, or a SecurityException
290:                     * will be thrown.
291:                     */
292:
293:                    ClassLoader cl = p.getClass().getClassLoader();
294:                    Class<?> implClass;
295:                    if (cl != null) {
296:                        implClass = cl.loadClass(className);
297:                    } else {
298:                        implClass = Class.forName(className);
299:                    }
300:
301:                    if (baseClass.isAssignableFrom(implClass)) {
302:
303:                        java.lang.reflect.Constructor<?> c = implClass
304:                                .getConstructor(Integer.TYPE);
305:                        MechanismFactory mf = (MechanismFactory) (c
306:                                .newInstance(caller));
307:
308:                        if (mf instanceof  NativeGSSFactory) {
309:                            ((NativeGSSFactory) mf).setMech(mechOid);
310:                        }
311:                        return mf;
312:                    } else {
313:                        throw createGSSException(p, className, "is not a "
314:                                + SPI_MECH_FACTORY_TYPE, null);
315:                    }
316:                } catch (ClassNotFoundException e) {
317:                    throw createGSSException(p, className, "cannot be created",
318:                            e);
319:                } catch (NoSuchMethodException e) {
320:                    throw createGSSException(p, className, "cannot be created",
321:                            e);
322:                } catch (InvocationTargetException e) {
323:                    throw createGSSException(p, className, "cannot be created",
324:                            e);
325:                } catch (InstantiationException e) {
326:                    throw createGSSException(p, className, "cannot be created",
327:                            e);
328:                } catch (IllegalAccessException e) {
329:                    throw createGSSException(p, className, "cannot be created",
330:                            e);
331:                } catch (SecurityException e) {
332:                    throw createGSSException(p, className, "cannot be created",
333:                            e);
334:                }
335:            }
336:
337:            // Only used by getMechFactoryImpl
338:            private static GSSException createGSSException(Provider p,
339:                    String className, String trailingMsg, Exception cause) {
340:                String errClassInfo = className + " configured by "
341:                        + p.getName() + " for GSS-API Mechanism Factory ";
342:                return new GSSExceptionImpl(GSSException.BAD_MECH, errClassInfo
343:                        + trailingMsg, cause);
344:            }
345:
346:            public Oid[] getMechs() {
347:                return mechs.toArray(new Oid[] {});
348:            }
349:
350:            synchronized public void addProviderAtFront(Provider p, Oid mechOid)
351:                    throws GSSException {
352:
353:                PreferencesEntry newEntry = new PreferencesEntry(p, mechOid);
354:                PreferencesEntry oldEntry;
355:                boolean foundSomeMech;
356:
357:                Iterator<PreferencesEntry> list = preferences.iterator();
358:                while (list.hasNext()) {
359:                    oldEntry = list.next();
360:                    if (newEntry.implies(oldEntry))
361:                        list.remove();
362:                }
363:
364:                if (mechOid == null) {
365:                    foundSomeMech = addAllMechsFromProvider(p);
366:                } else {
367:                    String oidStr = mechOid.toString();
368:                    if (p.getProperty(PROV_PROP_PREFIX + oidStr) == null)
369:                        throw new GSSExceptionImpl(GSSException.BAD_MECH,
370:                                "Provider " + p.getName()
371:                                        + " does not support " + oidStr);
372:                    mechs.add(mechOid);
373:                    foundSomeMech = true;
374:                }
375:
376:                if (foundSomeMech) {
377:                    preferences.add(0, newEntry);
378:                }
379:            }
380:
381:            synchronized public void addProviderAtEnd(Provider p, Oid mechOid)
382:                    throws GSSException {
383:
384:                PreferencesEntry newEntry = new PreferencesEntry(p, mechOid);
385:                PreferencesEntry oldEntry;
386:                boolean foundSomeMech;
387:
388:                Iterator<PreferencesEntry> list = preferences.iterator();
389:                while (list.hasNext()) {
390:                    oldEntry = list.next();
391:                    if (oldEntry.implies(newEntry))
392:                        return;
393:                }
394:
395:                // System.out.println("addProviderAtEnd: No it is not redundant");
396:
397:                if (mechOid == null)
398:                    foundSomeMech = addAllMechsFromProvider(p);
399:                else {
400:                    String oidStr = mechOid.toString();
401:                    if (p.getProperty(PROV_PROP_PREFIX + oidStr) == null)
402:                        throw new GSSExceptionImpl(GSSException.BAD_MECH,
403:                                "Provider " + p.getName()
404:                                        + " does not support " + oidStr);
405:                    mechs.add(mechOid);
406:                    foundSomeMech = true;
407:                }
408:
409:                if (foundSomeMech) {
410:                    preferences.add(newEntry);
411:                }
412:            }
413:
414:            /**
415:             * Helper routine to go through all properties contined in a
416:             * provider and add its mechanisms to the list of supported
417:             * mechanisms. If no default mechanism has been assinged so far,
418:             * it sets the default MechanismFactory and Oid as well.
419:             * @param p the provider to query
420:             * @return true if there is at least one mechanism that this
421:             * provider contributed, false otherwise
422:             */
423:            private boolean addAllMechsFromProvider(Provider p) {
424:
425:                String prop;
426:                boolean retVal = false;
427:
428:                // Get all props for this provider
429:                Enumeration<Object> props = p.keys();
430:
431:                // See if there are any GSS prop's
432:                while (props.hasMoreElements()) {
433:                    prop = (String) props.nextElement();
434:                    if (isMechFactoryProperty(prop)) {
435:                        // Ok! This is a GSS provider!
436:                        try {
437:                            Oid mechOid = getOidFromMechFactoryProperty(prop);
438:                            mechs.add(mechOid);
439:                            retVal = true;
440:                        } catch (GSSException e) {
441:                            // Skip to next property
442:                            GSSUtil.debug("Ignore the invalid property " + prop
443:                                    + " from provider " + p.getName());
444:                        }
445:                    } // Processed GSS property
446:                } // while loop
447:
448:                return retVal;
449:
450:            }
451:
452:            /**
453:             * Stores a provider and a mechanism oid indicating that the
454:             * provider should be used for the mechanism. If the mechanism
455:             * Oid is null, then it indicates that this preference holds for
456:             * any mechanism.<p>
457:             *
458:             * The ProviderList maintains an ordered list of
459:             * PreferencesEntry's and iterates thru them as it tries to
460:             * instantiate MechanismFactory's.
461:             */
462:            private static final class PreferencesEntry {
463:                private Provider p;
464:                private Oid oid;
465:
466:                PreferencesEntry(Provider p, Oid oid) {
467:                    this .p = p;
468:                    this .oid = oid;
469:                }
470:
471:                public boolean equals(Object other) {
472:                    if (this  == other) {
473:                        return true;
474:                    }
475:
476:                    if (!(other instanceof  PreferencesEntry)) {
477:                        return false;
478:                    }
479:
480:                    PreferencesEntry that = (PreferencesEntry) other;
481:                    if (this .p.getName().equals(that.p.getName())) {
482:                        if (this .oid != null && that.oid != null) {
483:                            return this .oid.equals(that.oid);
484:                        } else {
485:                            return (this .oid == null && that.oid == null);
486:                        }
487:                    }
488:
489:                    return false;
490:                }
491:
492:                public int hashCode() {
493:                    int result = 17;
494:
495:                    result = 37 * result + p.getName().hashCode();
496:                    if (oid != null) {
497:                        result = 37 * result + oid.hashCode();
498:                    }
499:
500:                    return result;
501:                }
502:
503:                /**
504:                 * Determines if a preference implies another. A preference
505:                 * implies another if the latter is subsumed by the
506:                 * former. e.g., <Provider1, null> implies <Provider1, OidX>
507:                 * because the null in the former indicates that it should
508:                 * be used for all mechanisms.
509:                 */
510:                boolean implies(Object other) {
511:
512:                    if (other instanceof  PreferencesEntry) {
513:                        PreferencesEntry temp = (PreferencesEntry) other;
514:                        return (equals(temp) || p.getName().equals(
515:                                temp.p.getName())
516:                                && oid == null);
517:                    } else {
518:                        return false;
519:                    }
520:                }
521:
522:                Provider getProvider() {
523:                    return p;
524:                }
525:
526:                Oid getOid() {
527:                    return oid;
528:                }
529:
530:                /**
531:                 * Determines if this entry is applicable to the desired
532:                 * mechanism. The entry is applicable to the desired mech if
533:                 * it contains the same oid or if it contains a null oid
534:                 * indicating that it is applicable to all mechs.
535:                 * @param mechOid the desired mechanism
536:                 * @return true if the provider in this entry should be
537:                 * queried for this mechanism.
538:                 */
539:                boolean impliesMechanism(Oid oid) {
540:                    return (this .oid == null || this .oid.equals(oid));
541:                }
542:
543:                // For debugging
544:                public String toString() {
545:                    StringBuffer buf = new StringBuffer("<");
546:                    buf.append(p.getName());
547:                    buf.append(", ");
548:                    buf.append(oid);
549:                    buf.append(">");
550:                    return buf.toString();
551:                }
552:            }
553:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.