KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > enterprise > iiop > security > GSSUPToken


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23 package com.sun.enterprise.iiop.security;
24
25 /**
26  * GSSUPToken class creates a mechanism specific gssapi token for
27  * the username, password mechanism
28  * @author Sekhar Vajjhala
29  */

30
31 import java.io.IOException JavaDoc;
32 import org.omg.CORBA.*;
33 import org.omg.PortableInterceptor.*;
34 import org.omg.IOP.*;
35
36
37 import java.util.*;
38
39 /* Import CSIV2 idl generated classes */
40 import com.sun.corba.ee.org.omg.CSI.*;
41 import com.sun.corba.ee.org.omg.GSSUP.*;
42 import com.sun.corba.ee.org.omg.CSIIOP.*;
43
44 import com.sun.enterprise.iiop.security.GSSUtils;
45 import com.sun.enterprise.security.auth.login.PasswordCredential;
46
47 import java.util.logging.*;
48 import com.sun.logging.*;
49 /**
50  * GSSUPToken Represents the on the wire username/password credential on the
51  * client side and the server side.
52  * @author Sekhar Vajjhala
53  * @author Harpreet Singh
54  */

55
56 public class GSSUPToken {
57     private static java.util.logging.Logger JavaDoc _logger=null;
58     
59     static{
60        _logger=LogDomains.getLogger(LogDomains.CORBA_LOGGER);
61     }
62     //START OF IASRI 4825735.
63
// to allow for usernames of the type user@foobar.com
64
// Will be represented as user\\@foobar.com@domain
65
public static final String JavaDoc DELIMITER_REGEXP = "\\@";
66     // backslash for regexp is denoted as \\
67
public static final String JavaDoc ESCAPE_CHAR_REGEXP = "\\\\\\@";
68     public static final String JavaDoc ESCAPE_CHAR = "\\";
69     //START OF IASRI 4825735
70

71     public static final String JavaDoc DELIMITER = "@" ;
72     public static final String JavaDoc DEFAULT_REALM_NAME = "default";
73     
74     /**
75      * cdr_encoded_token is the GSSAPI mechanism specific token
76      * for the user, password mechanism. The mechanism specific
77      * token is stored in the CDR encoded form.
78      */

79     private byte[] cdr_encoded_token = {} ;
80
81     /* PasswordCredential that contains the username, password and realm */
82     PasswordCredential pwdcred = null;
83     /**
84      * Constructs mechanism token from a password credential, called from
85      * the client side interceptors
86      * @param orb the ORB
87      * @param codec the codec for translation
88      * @param pwdcred the Password credential, populated with username/password
89      * and the realm name
90      * @return GSSUPToken instance of the GSSUPToken class.
91      * @since 1.4
92      */

93     public static GSSUPToken getClientSideInstance(ORB orb, Codec codec,
94                     PasswordCredential pwdcred){
95         return new GSSUPToken(orb, codec, pwdcred);
96     }
97     /**
98      * Creates a GSSUPToken instance on the server side
99      * @param orb the orb
100      * @param codec the codec
101      * @param authok the authtoken received on the wire.
102      * @throws SecurityMechanismException if a name/value pair is not found in
103      * the authtok
104      * @since 1.4
105      */

106     public static GSSUPToken getServerSideInstance(ORB orb, Codec codec,
107                     byte[] authtok) throws SecurityMechanismException{
108         return new GSSUPToken(orb, codec, authtok);
109     }
110     
111     /**
112      * Constructor used to construct a mechansim token from a
113      * PasswordCredential. This is used by a context initiator.
114      * This is called on the Client Side
115      */

116     private GSSUPToken(ORB orb, Codec codec, PasswordCredential pwdcred)
117     {
118         byte[] name_utf8 = {}; // username in UTF8 format
119
byte[] password_utf8 = {}; // password in UTF8 format
120

121         if(_logger.isLoggable(Level.FINE)){
122             _logger.log(Level.FINE,"IIOP: Going to construct a GSSUPToken:");
123             _logger.log(Level.FINE, pwdcred.toString());
124         }
125
126         try {
127             String JavaDoc _name_ = new String JavaDoc(pwdcred.getUser());
128             // if username is of type user@sun.com, realm - foo
129
// do the following
130
// create user\\@sun.com
131
// if username is already of the type user\\@foo, dont do anything
132
int index = _name_.indexOf(DELIMITER);
133             if(index == -1){
134                 // no @ - ignore
135
}else{ // check if it is already escaped
136
int escaped_index = _name_.indexOf(ESCAPE_CHAR);
137                 if(escaped_index == -1){ // delimiter not escaped, escape it
138
_name_ = _name_.replaceAll(DELIMITER_REGEXP, ESCAPE_CHAR_REGEXP);
139                 }else{ // some are escaped, some may be not
140
// rather than traversing the string and escaping
141
// some that are not escaped
142
// just remove the escape on all escaped delimiters
143
// and then re-escape them
144
_name_ = _name_.replaceAll(ESCAPE_CHAR_REGEXP, DELIMITER_REGEXP);
145                     _name_ = _name_.replaceAll(DELIMITER_REGEXP, ESCAPE_CHAR_REGEXP);
146                 }
147             }
148             String JavaDoc realm = pwdcred.getRealm();
149             // concatenation of name+realm
150
if(realm != null){
151                 // cannot use StringBuffer, as StringBuffer eats away a \
152
_name_ = _name_ + DELIMITER + realm;
153             }
154             name_utf8 = _name_.toString().getBytes("UTF8");
155             password_utf8 = pwdcred.getPassword().getBytes("UTF8");
156         } catch (Exception JavaDoc e) {
157             _logger.log(Level.SEVERE,"iiop.password_exception",e);
158         }
159
160         /* Get the target name from the IOR. The IOR is stored in the
161          * ConnectionContext object
162          */

163
164         SecurityMechanismSelector sms = new SecurityMechanismSelector();
165         ConnectionContext cc = sms.getClientConnectionContext();
166         CompoundSecMech mech = cc.getMechanism();
167         byte[] target_name = mech.as_context_mech.target_name;
168
169         if(_logger.isLoggable(Level.FINE)){
170             _logger.fine("Username (UTF8) " + GSSUtils.dumpHex(name_utf8));
171             _logger.fine("Password (UTF8) " + GSSUtils.dumpHex(password_utf8));
172             _logger.fine("Targetname " + GSSUtils.dumpHex(target_name));
173         }
174  
175         /* Create an InitialContextToken */
176         InitialContextToken inctxToken =
177             new InitialContextToken(name_utf8, password_utf8, target_name);
178
179         /* Generate a CDR encoding */
180         Any a = orb.create_any();
181         InitialContextTokenHelper.insert(a, inctxToken);
182
183         try {
184         cdr_encoded_token = codec.encode_value(a);
185         } catch (Exception JavaDoc e) {
186             _logger.log(Level.SEVERE,"iiop.encode_exception",e);
187         }
188     if(_logger.isLoggable(Level.FINE)) {
189         _logger.log(Level.FINE,"IIOP:Mech specific token length (CDR encoded) = " + cdr_encoded_token.length);
190     }
191     }
192
193     /* Constructor used to construct a mechansim token from a CDR encoded
194      * mechanism specific token. This is used by a context acceptor.
195      * This is called on the server side.
196      */

197
198     private GSSUPToken(ORB orb, Codec codec, byte[] authtok)
199     throws SecurityMechanismException
200     {
201         byte[] name_utf8 = {}; // username in UTF8 format
202
byte[] password_utf8 = {}; // password in UTF8 format
203
byte[] target_name = {} ; // target name
204
String JavaDoc username = "";
205         String JavaDoc userpwd = "";
206         String JavaDoc realm = "";
207         byte[] encoded_token = {} ;
208
209        if(_logger.isLoggable(Level.FINE)) {
210             _logger.log(Level.FINE, "IIOP:Going to construct a GSSUPToken:");
211             _logger.log(Level.FINE, "IIOP:Getting CDR encoded GSSUP mechanism token from client authentication token");
212        }
213         /* get CDR encoded mechanism specific token */
214         encoded_token = GSSUtils.getMechToken(GSSUtils.GSSUP_MECH_OID, authtok);
215         
216         /* create a GSSUPToken from the authentication token */
217         if(_logger.isLoggable(Level.FINE)) {
218              _logger.log(Level.FINE,"CDR encoded mech specific token length = "+ encoded_token.length);
219         }
220         /* Decode the cdr encoded token */
221         Any a = orb.create_any();
222
223         try {
224         a = codec.decode_value(encoded_token, InitialContextTokenHelper.type());
225         } catch (Exception JavaDoc e) {
226             _logger.log(Level.SEVERE,"iiop.decode_exception",e);
227         }
228
229         InitialContextToken inctxToken = InitialContextTokenHelper.extract(a);
230
231         /* get UTF8 encodings from initial context token */
232         password_utf8 = inctxToken.password;
233         name_utf8 = inctxToken.username;
234         target_name = inctxToken.target_name;
235
236         if(_logger.isLoggable(Level.FINE)){
237             _logger.fine("IIOP:Username (UTF8) " + GSSUtils.dumpHex(name_utf8));
238             _logger.fine("IIOP:Password (UTF8) " + GSSUtils.dumpHex(password_utf8));
239             _logger.fine("IIOP:Targetname " + GSSUtils.dumpHex(target_name));
240         }
241         /* Construct a PasswordCredential */
242
243         try {
244             username = new String JavaDoc(name_utf8, "UTF8");
245             userpwd = new String JavaDoc(password_utf8, "UTF8");
246     } catch (Exception JavaDoc e) {
247             _logger.log(Level.SEVERE,"iiop.user_password_exception",e);
248     }
249
250         /**
251          * decode the username and realm as specified by CSIV2
252          */

253     String JavaDoc name;
254     int index = username.indexOf(DELIMITER);
255         int esc_index = username.indexOf(ESCAPE_CHAR);
256         if ( index == -1 ) {
257             name = username;
258         }
259         else if ( index == 0 || esc_index == 0) {
260             // username is of the form "@realm" or
261
// \\@realm or starts with a escape character
262
throw new SecurityMechanismException("No name_value in username");
263         } else if (esc_index != -1){
264             // START IASRI 4825735 - Changed from 7.0 UR1 to take
265
// care of realm-per-app features
266
// username\\@sun.com@realm type
267
if (esc_index+2 >= username.length()){
268                 // string ends at username\\@ - nothing follows
269
name = username.replaceAll(ESCAPE_CHAR_REGEXP, DELIMITER);
270                 if(_logger.isLoggable(Level.FINE)){
271                     _logger.log(Level.FINE, "IIOP:No Realm specified, "+
272                     " creating a default realm for login");
273                 }
274                 realm = DEFAULT_REALM_NAME;
275             }else {
276                 // locate the second @ token
277
// index+2 starts from the first @ sign and thus
278
// returns the index of the first @ sign
279
// index +3 skips this @ and gives the index of second @
280
int second_at_index = username.indexOf(DELIMITER, esc_index+3);
281                 if (second_at_index == -1){
282                     // user\\@foobar.com - no realm specified
283
name = username.replaceAll(ESCAPE_CHAR_REGEXP, DELIMITER);
284
285                     if(_logger.isLoggable(Level.FINE)){
286                         _logger.log(Level.FINE, "IIOP:No Realm specified, "+
287                         " creating a default realm for login");
288                     }
289                     realm = DEFAULT_REALM_NAME;
290                 }else {
291                     name = username.substring(0, second_at_index);
292                     name = name.replaceAll(ESCAPE_CHAR_REGEXP, DELIMITER);
293                     realm = username.substring(second_at_index+1);
294                     if(realm == null){
295                         // user\\@foo.com@ type
296
if(_logger.isLoggable(Level.FINE)){
297                             _logger.log(Level.FINE, "IIOP:No Realm specified, "+
298                             " creating a default realm for login");
299                         }
300                         realm = DEFAULT_REALM_NAME;
301                     }
302                 }
303             }
304             // End IASRI 4825735 - Changed from 7.0 UR1
305
} else {
306         // parse the name and realm tokens
307
StringTokenizer strtok = new StringTokenizer(username, DELIMITER);
308         name = strtok.nextToken();
309         // this checking is neccessary if the username="name@"
310
if ( strtok.hasMoreTokens() ) {
311             realm = strtok.nextToken();
312                 // for realm-per-app
313
// if ( !realm.equals("default") )
314
// throw new SecurityMechanismException("Unknown realm");
315
if(realm == null){
316                     if(_logger.isLoggable(Level.FINE)){
317                         _logger.log(Level.FINE, "IIOP:No Realm specified, "+
318                             " creating a default realm for login");
319                     }
320                     realm = DEFAULT_REALM_NAME;
321                 }
322             }
323     }
324         pwdcred = new PasswordCredential(name, userpwd, realm, target_name);
325         if(_logger.isLoggable(Level.FINE)){
326             _logger.log(Level.FINE, pwdcred.toString());
327         }
328     }
329     /**
330      * Returns the GSSToken for the GSSUPToken name that conforms to
331      * the GSSUP Mechanism id
332      * @return byte[] the byte array representation of the GSSToken
333      */

334     byte[] getGSSToken() throws IOException JavaDoc
335     {
336         if(_logger.isLoggable(Level.FINER)){
337             _logger.log(Level.FINER, "IIOP:GSSUP mech token : " + GSSUtils.dumpHex(cdr_encoded_token));
338         }
339          /* construct a GSSAPI token ( hdr + mechanism token ) */
340          byte[] gsstoken = GSSUtils.createMechIndToken(GSSUtils.GSSUP_MECH_OID, cdr_encoded_token);
341          if(_logger.isLoggable(Level.FINER)){
342              _logger.log(Level.FINER, "IIOP:GSSUP token length : " + gsstoken.length);
343              _logger.log(Level.FINER, "IIOP:GSSUP token: " + GSSUtils.dumpHex(gsstoken));
344          }
345          return gsstoken;
346     }
347     
348     /**
349      * @return PasswordCredential the PasswordCredential object that has the
350      * username and password. This is called from the server side interceptor
351      */

352     PasswordCredential getPwdcred()
353     {
354        return pwdcred;
355     }
356 }
357
358
Popular Tags