Source Code Cross Referenced for GSSNameImpl.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 org.ietf.jgss.*;
029:        import sun.security.jgss.spi.*;
030:        import java.util.Set;
031:        import java.util.HashMap;
032:        import java.util.HashSet;
033:        import java.util.Arrays;
034:        import java.io.IOException;
035:        import java.io.UnsupportedEncodingException;
036:        import sun.security.util.ObjectIdentifier;
037:        import sun.security.util.DerInputStream;
038:        import sun.security.util.DerOutputStream;
039:
040:        /**
041:         * This is the implementation class for GSSName. Conceptually the
042:         * GSSName is a container with mechanism specific name elements. Each 
043:         * name element is a representation of how that particular mechanism
044:         * would canonicalize this principal.
045:         *
046:         * Generally a GSSName is created by an application when it supplies 
047:         * a sequence of bytes and a nametype that helps each mechanism
048:         * decide how to interpret those bytes.
049:         *
050:         * It is not necessary to create name elements for each available
051:         * mechanism at the time the application creates the GSSName. This
052:         * implementation does this lazily, as and when name elements for
053:         * mechanisms are required to be handed out. (Generally, other GSS
054:         * classes like GSSContext and GSSCredential request specific
055:         * elements depending on the mechanisms that they are dealing with.)
056:         * Assume that getting a mechanism to parse the applciation specified
057:         * bytes is an expensive call.
058:         *
059:         * When a GSSName is canonicalized wrt some mechanism, it is supposed
060:         * to discard all elements of other mechanisms and retain only the
061:         * element for this mechanism. In GSS terminology this is called a
062:         * Mechanism Name or MN. This implementation tries to retain the
063:         * application provided bytes and name type just in case the MN is
064:         * asked to produce an element for a mechanism that is different.
065:         *
066:         * When a GSSName is to be exported, the name element for the desired
067:         * mechanism is converted to a byte representation and written
068:         * out. It might happen that a name element for that mechanism cannot 
069:         * be obtained. This happens when the mechanism is just not supported 
070:         * in this GSS-API or when the mechanism is supported but bytes
071:         * corresponding to the nametypes that it understands are not
072:         * available in this GSSName.
073:         *
074:         * This class is safe for sharing. Each retrieval of a name element
075:         * from getElement() might potentially add a new element to the
076:         * hashmap of elements, but getElement() is synchronized.
077:         *
078:         * @author Mayank Upadhyay
079:         * @version 1.24, 05/05/07
080:         * @since 1.4
081:         */
082:
083:        public class GSSNameImpl implements  GSSName {
084:
085:            private GSSManagerImpl gssManager = null;
086:
087:            /*
088:             * Store whatever the application passed in. We will use this to
089:             * get individual mechanisms to create name elements as and when
090:             * needed.
091:             * Store both the String and the byte[]. Leave I18N to the
092:             * mechanism by allowing it to extract bytes from the String!
093:             */
094:
095:            private String appNameStr = null;
096:            private byte[] appNameBytes = null;
097:            private Oid appNameType = null;
098:
099:            /*
100:             * When we figure out what the printable name would be, we store
101:             * both the name and its type.
102:             */
103:
104:            private String printableName = null;
105:            private Oid printableNameType = null;
106:
107:            private HashMap<Oid, GSSNameSpi> elements = null;
108:            private GSSNameSpi mechElement = null;
109:
110:            static GSSNameImpl wrapElement(GSSManagerImpl gssManager,
111:                    GSSNameSpi mechElement) throws GSSException {
112:                return (mechElement == null ? null : new GSSNameImpl(
113:                        gssManager, mechElement));
114:            }
115:
116:            GSSNameImpl(GSSManagerImpl gssManager, GSSNameSpi mechElement) {
117:                this .gssManager = gssManager;
118:                appNameStr = printableName = mechElement.toString();
119:                appNameType = printableNameType = mechElement
120:                        .getStringNameType();
121:                this .mechElement = mechElement;
122:                elements = new HashMap<Oid, GSSNameSpi>(1);
123:                elements.put(mechElement.getMechanism(), this .mechElement);
124:            }
125:
126:            GSSNameImpl(GSSManagerImpl gssManager, Object appName,
127:                    Oid appNameType) throws GSSException {
128:                this (gssManager, appName, appNameType, null);
129:            }
130:
131:            GSSNameImpl(GSSManagerImpl gssManager, Object appName,
132:                    Oid appNameType, Oid mech) throws GSSException {
133:
134:                if (appName == null)
135:                    throw new GSSExceptionImpl(GSSException.BAD_NAME,
136:                            "Cannot import null name");
137:                if (mech == null)
138:                    mech = ProviderList.DEFAULT_MECH_OID;
139:                if (NT_EXPORT_NAME.equals(appNameType)) {
140:                    importName(gssManager, appName);
141:                } else {
142:                    init(gssManager, appName, appNameType, mech);
143:                }
144:            }
145:
146:            private void init(GSSManagerImpl gssManager, Object appName,
147:                    Oid appNameType, Oid mech) throws GSSException {
148:
149:                this .gssManager = gssManager;
150:                this .elements = new HashMap<Oid, GSSNameSpi>(gssManager
151:                        .getMechs().length);
152:
153:                if (appName instanceof  String) {
154:                    this .appNameStr = (String) appName;
155:                    /*
156:                     * If appNameType is null, then the nametype for this printable
157:                     * string is determined only by interrogating the
158:                     * mechanism. Thus, defer the setting of printableName and
159:                     * printableNameType till later.
160:                     */
161:                    if (appNameType != null) {
162:                        printableName = appNameStr;
163:                        printableNameType = appNameType;
164:                    }
165:                } else {
166:                    this .appNameBytes = (byte[]) appName;
167:                }
168:
169:                this .appNameType = appNameType;
170:
171:                mechElement = getElement(mech);
172:
173:                /*
174:                 * printableName will be null if appName was in a byte[] or if
175:                 * appName was in a String but appNameType was null.
176:                 */
177:                if (printableName == null) {
178:                    printableName = mechElement.toString();
179:                    printableNameType = mechElement.getStringNameType();
180:                }
181:
182:                /*
183:                 *  At this point the GSSNameImpl has the following set:
184:                 *   appNameStr or appNameBytes
185:                 *   appNameType (could be null)
186:                 *   printableName
187:                 *   printableNameType
188:                 *   mechElement (which also exists in the hashmap of elements)
189:                 */
190:            }
191:
192:            private void importName(GSSManagerImpl gssManager, Object appName)
193:                    throws GSSException {
194:
195:                int pos = 0;
196:                byte[] bytes = null;
197:
198:                if (appName instanceof  String) {
199:                    try {
200:                        bytes = ((String) appName).getBytes("UTF-8");
201:                    } catch (UnsupportedEncodingException e) {
202:                        // Won't happen
203:                    }
204:                } else
205:                    bytes = (byte[]) appName;
206:
207:                if ((bytes[pos++] != 0x04) || (bytes[pos++] != 0x01))
208:                    throw new GSSExceptionImpl(GSSException.BAD_NAME,
209:                            "Exported name token id is corrupted!");
210:
211:                int oidLen = (((0xFF & bytes[pos++]) << 8) | (0xFF & bytes[pos++]));
212:                ObjectIdentifier temp = null;
213:                try {
214:                    DerInputStream din = new DerInputStream(bytes, pos, oidLen);
215:                    temp = new ObjectIdentifier(din);
216:                } catch (IOException e) {
217:                    throw new GSSExceptionImpl(GSSException.BAD_NAME,
218:                            "Exported name Object identifier is corrupted!");
219:                }
220:                Oid oid = new Oid(temp.toString());
221:                pos += oidLen;
222:                int mechPortionLen = (((0xFF & bytes[pos++]) << 24)
223:                        | ((0xFF & bytes[pos++]) << 16)
224:                        | ((0xFF & bytes[pos++]) << 8) | (0xFF & bytes[pos++]));
225:                byte[] mechPortion = new byte[mechPortionLen];
226:                System.arraycopy(bytes, pos, mechPortion, 0, mechPortionLen);
227:
228:                init(gssManager, mechPortion, NT_EXPORT_NAME, oid);
229:            }
230:
231:            public GSSName canonicalize(Oid mech) throws GSSException {
232:                if (mech == null)
233:                    mech = ProviderList.DEFAULT_MECH_OID;
234:
235:                return wrapElement(gssManager, getElement(mech));
236:            }
237:
238:            /**
239:             * This method may return false negatives. But if it says two
240:             * names are equals, then there is some mechanism that
241:             * authenticates them as the same principal.
242:             */
243:            public boolean equals(GSSName other) throws GSSException {
244:
245:                if (this .isAnonymous() || other.isAnonymous())
246:                    return false;
247:
248:                if (other == this )
249:                    return true;
250:
251:                if (!(other instanceof  GSSNameImpl))
252:                    return equals(gssManager.createName(other.toString(), other
253:                            .getStringNameType()));
254:
255:                /*
256:                 * XXX Do a comparison of the appNameStr/appNameBytes if
257:                 * available. If that fails, then proceed with this test.
258:                 */
259:
260:                GSSNameImpl that = (GSSNameImpl) other;
261:
262:                GSSNameSpi myElement = this .mechElement;
263:                GSSNameSpi element = that.mechElement;
264:
265:                /*
266:                 * XXX If they are not of the same mechanism type, convert both to 
267:                 * Kerberos since it is guaranteed to be present.
268:                 */
269:                if ((myElement == null) && (element != null)) {
270:                    myElement = this .getElement(element.getMechanism());
271:                } else if ((myElement != null) && (element == null)) {
272:                    element = that.getElement(myElement.getMechanism());
273:                }
274:
275:                if (myElement != null && element != null) {
276:                    return myElement.equals(element);
277:                }
278:
279:                if ((this .appNameType != null) && (that.appNameType != null)) {
280:                    if (!this .appNameType.equals(that.appNameType)) {
281:                        return false;
282:                    }
283:                    byte[] myBytes = null;
284:                    byte[] bytes = null;
285:                    try {
286:                        myBytes = (this .appNameStr != null ? this .appNameStr
287:                                .getBytes("UTF-8") : this .appNameBytes);
288:                        bytes = (that.appNameStr != null ? that.appNameStr
289:                                .getBytes("UTF-8") : that.appNameBytes);
290:                    } catch (UnsupportedEncodingException e) {
291:                        // Won't happen
292:                    }
293:
294:                    return Arrays.equals(myBytes, bytes);
295:                }
296:
297:                return false;
298:
299:            }
300:
301:            /**
302:             * Returns a hashcode value for this GSSName.
303:             *
304:             * @return a hashCode value
305:             */
306:            public int hashCode() {
307:                /*
308:                 * XXX
309:                 * In order to get this to work reliably and properly(!), obtain a
310:                 * Kerberos name element for the name and then call hashCode on its 
311:                 * string representation. But this cannot be done if the nametype
312:                 * is not one of those supported by the Kerberos provider and hence 
313:                 * this name cannot be imported by Kerberos. In that case return a
314:                 * constant value!
315:                 */
316:
317:                return 1;
318:            }
319:
320:            public boolean equals(Object another) {
321:
322:                try {
323:                    // XXX This can lead to an infinite loop. Extract info
324:                    // and create a GSSNameImpl with it.
325:
326:                    if (another instanceof  GSSName)
327:                        return equals((GSSName) another);
328:                } catch (GSSException e) {
329:                    // Squelch it and return false
330:                }
331:
332:                return false;
333:            }
334:
335:            /**
336:             * Returns a flat name representation for this object. The name
337:             * format is defined in RFC 2743:
338:             *<pre>
339:             * Length           Name          Description
340:             * 2               TOK_ID          Token Identifier
341:             *                                 For exported name objects, this
342:             *                                 must be hex 04 01.
343:             * 2               MECH_OID_LEN    Length of the Mechanism OID
344:             * MECH_OID_LEN    MECH_OID        Mechanism OID, in DER
345:             * 4               NAME_LEN        Length of name
346:             * NAME_LEN        NAME            Exported name; format defined in
347:             *                                 applicable mechanism draft.
348:             *</pre>
349:             *
350:             * Note that it is not required to canonicalize a name before
351:             * calling export(). i.e., the name need not be an MN. If it is
352:             * not an MN, an implementation defined algorithm can be used for 
353:             * choosing the mechanism which should export this name.
354:             *
355:             * @return the flat name representation for this object
356:             * @exception GSSException with major codes NAME_NOT_MN, BAD_NAME,
357:             *	BAD_NAME, FAILURE.   
358:             */
359:            public byte[] export() throws GSSException {
360:
361:                if (mechElement == null) {
362:                    /* Use default mech */
363:                    mechElement = getElement(ProviderList.DEFAULT_MECH_OID);
364:                }
365:
366:                byte[] mechPortion = mechElement.export();
367:                byte[] oidBytes = null;
368:                ObjectIdentifier oid = null;
369:
370:                try {
371:                    oid = new ObjectIdentifier(mechElement.getMechanism()
372:                            .toString());
373:                } catch (IOException e) {
374:                    throw new GSSExceptionImpl(GSSException.FAILURE,
375:                            "Invalid OID String ");
376:                }
377:                DerOutputStream dout = new DerOutputStream();
378:                try {
379:                    dout.putOID(oid);
380:                } catch (IOException e) {
381:                    throw new GSSExceptionImpl(GSSException.FAILURE,
382:                            "Could not ASN.1 Encode " + oid.toString());
383:                }
384:                oidBytes = dout.toByteArray();
385:
386:                byte[] retVal = new byte[2 + 2 + oidBytes.length + 4
387:                        + mechPortion.length];
388:                int pos = 0;
389:                retVal[pos++] = 0x04;
390:                retVal[pos++] = 0x01;
391:                retVal[pos++] = (byte) (oidBytes.length >>> 8);
392:                retVal[pos++] = (byte) oidBytes.length;
393:                System.arraycopy(oidBytes, 0, retVal, pos, oidBytes.length);
394:                pos += oidBytes.length;
395:                retVal[pos++] = (byte) (mechPortion.length >>> 24);
396:                retVal[pos++] = (byte) (mechPortion.length >>> 16);
397:                retVal[pos++] = (byte) (mechPortion.length >>> 8);
398:                retVal[pos++] = (byte) mechPortion.length;
399:                System.arraycopy(mechPortion, 0, retVal, pos,
400:                        mechPortion.length);
401:                return retVal;
402:            }
403:
404:            public String toString() {
405:                return printableName;
406:
407:            }
408:
409:            public Oid getStringNameType() throws GSSException {
410:                return printableNameType;
411:            }
412:
413:            public boolean isAnonymous() {
414:                if (printableNameType == null) {
415:                    return false;
416:                } else {
417:                    return GSSName.NT_ANONYMOUS.equals(printableNameType);
418:                }
419:            }
420:
421:            public boolean isMN() {
422:                return true; // Since always canonicalized for some mech
423:            }
424:
425:            public synchronized GSSNameSpi getElement(Oid mechOid)
426:                    throws GSSException {
427:
428:                GSSNameSpi retVal = elements.get(mechOid);
429:
430:                if (retVal == null) {
431:                    if (appNameStr != null) {
432:                        retVal = gssManager.getNameElement(appNameStr,
433:                                appNameType, mechOid);
434:                    } else {
435:                        retVal = gssManager.getNameElement(appNameBytes,
436:                                appNameType, mechOid);
437:                    }
438:                    elements.put(mechOid, retVal);
439:                }
440:                return retVal;
441:            }
442:
443:            Set<GSSNameSpi> getElements() {
444:                return new HashSet<GSSNameSpi>(elements.values());
445:            }
446:
447:            private static String getNameTypeStr(Oid nameTypeOid) {
448:
449:                if (nameTypeOid == null)
450:                    return "(NT is null)";
451:
452:                if (nameTypeOid.equals(NT_USER_NAME))
453:                    return "NT_USER_NAME";
454:                if (nameTypeOid.equals(NT_HOSTBASED_SERVICE))
455:                    return "NT_HOSTBASED_SERVICE";
456:                if (nameTypeOid.equals(NT_EXPORT_NAME))
457:                    return "NT_EXPORT_NAME";
458:                if (nameTypeOid.equals(GSSUtil.NT_GSS_KRB5_PRINCIPAL))
459:                    return "NT_GSS_KRB5_PRINCIPAL";
460:                else
461:                    return "Unknown";
462:            }
463:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.