KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jacorb > security > sas > SASClientInterceptor


1 package org.jacorb.security.sas;
2
3 /*
4  * JacORB - a free Java ORB
5  *
6  * Copyright (C) 2000-2004 Nicolas Noffke, Gerald Brose.
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public
19  * License along with this library; if not, write to the Free
20  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21  */

22
23 import java.net.URLDecoder JavaDoc;
24 import java.util.Hashtable JavaDoc;
25
26 import org.apache.avalon.framework.configuration.Configurable;
27 import org.apache.avalon.framework.configuration.Configuration;
28 import org.apache.avalon.framework.configuration.ConfigurationException;
29 import org.apache.avalon.framework.logger.Logger;
30 import org.jacorb.orb.CDRInputStream;
31 import org.jacorb.orb.MinorCodes;
32 import org.jacorb.orb.giop.ClientConnection;
33 import org.jacorb.orb.portableInterceptor.ClientRequestInfoImpl;
34 import org.omg.ATLAS.ATLASProfile;
35 import org.omg.ATLAS.ATLASProfileHelper;
36 import org.omg.ATLAS.AuthTokenData;
37 import org.omg.ATLAS.AuthTokenDispenser;
38 import org.omg.ATLAS.AuthTokenDispenserHelper;
39 import org.omg.ATLAS.SCS_ATLAS;
40 import org.omg.CORBA.Any JavaDoc;
41 import org.omg.CORBA.BAD_PARAM JavaDoc;
42 import org.omg.CORBA.CompletionStatus JavaDoc;
43 import org.omg.CSI.AuthorizationElement;
44 import org.omg.CSI.CompleteEstablishContext;
45 import org.omg.CSI.ContextError;
46 import org.omg.CSI.EstablishContext;
47 import org.omg.CSI.IdentityToken;
48 import org.omg.CSI.MTCompleteEstablishContext;
49 import org.omg.CSI.MTContextError;
50 import org.omg.CSI.MessageInContext;
51 import org.omg.CSI.SASContextBody;
52 import org.omg.CSI.SASContextBodyHelper;
53 import org.omg.CSIIOP.CompoundSecMechList;
54 import org.omg.CSIIOP.CompoundSecMechListHelper;
55 import org.omg.CSIIOP.ServiceConfiguration;
56 import org.omg.CSIIOP.TAG_CSI_SEC_MECH_LIST;
57 import org.omg.IOP.Codec JavaDoc;
58 import org.omg.IOP.ENCODING_CDR_ENCAPS JavaDoc;
59 import org.omg.IOP.Encoding JavaDoc;
60 import org.omg.IOP.ServiceContext JavaDoc;
61 import org.omg.IOP.TaggedComponent JavaDoc;
62 import org.omg.IOP.CodecFactoryPackage.UnknownEncoding JavaDoc;
63 import org.omg.PortableInterceptor.ClientRequestInterceptor JavaDoc;
64 import org.omg.PortableInterceptor.ORBInitInfo JavaDoc;
65
66 /**
67  * This is the SAS Client Security Service (CSS) Interceptor
68  *
69  * @author David Robison
70  * @version $Id: SASClientInterceptor.java,v 1.25 2005/06/01 11:03:58 andre.spiegel Exp $
71  */

72
73 public class SASClientInterceptor
74     extends org.omg.CORBA.LocalObject JavaDoc
75     implements ClientRequestInterceptor JavaDoc, Configurable
76 {
77     protected static final int SecurityAttributeService = 15;
78     protected final String JavaDoc DEFAULT_NAME = "SASClientInterceptor";
79     protected Codec JavaDoc codec = null;
80     protected String JavaDoc name = null;
81
82     private Logger logger = null;
83
84     protected byte[] contextToken = new byte[0];
85     protected boolean useStateful = true;
86     protected Hashtable JavaDoc atlasCache = new Hashtable JavaDoc();
87
88     protected ISASContext sasContext = null;
89
90     public SASClientInterceptor(ORBInitInfo JavaDoc info)
91         throws UnknownEncoding JavaDoc, ConfigurationException
92     {
93         name = DEFAULT_NAME;
94         Encoding JavaDoc encoding = new Encoding JavaDoc(ENCODING_CDR_ENCAPS.value, (byte) 1, (byte) 0);
95         codec = info.codec_factory().create_codec(encoding);
96
97         org.jacorb.orb.ORB orb =
98             ((org.jacorb.orb.portableInterceptor.ORBInitInfoImpl)info).getORB ();
99         configure( orb.getConfiguration());
100     }
101
102     public void configure(Configuration configuration)
103         throws ConfigurationException
104     {
105         logger =
106             ((org.jacorb.config.Configuration)configuration).getNamedLogger("jacorb.security.sas.CSS");
107
108         useStateful =
109             configuration.getAttribute("jacorb.security.sas.stateful","true").equals("true");
110
111         String JavaDoc contextClass = null;
112         try
113         {
114             contextClass = configuration.getAttribute("jacorb.security.sas.contextClass");
115             Class JavaDoc c =
116                 org.jacorb.util.ObjectUtil.classForName(contextClass);
117             sasContext = (ISASContext)c.newInstance();
118         }
119         catch(ConfigurationException ce)
120         {
121             if (logger.isDebugEnabled())
122                 logger.debug("ConfigurationException", ce);
123         }
124         catch (Exception JavaDoc e)
125         {
126             if (logger.isErrorEnabled())
127                 logger.error("Could not instantiate class " + contextClass + ": " + e);
128         }
129
130         if (sasContext == null)
131         {
132             if (logger.isErrorEnabled())
133                 logger.error("Could not load SAS context class: "+contextClass);
134         }
135         else
136         {
137             sasContext.configure(configuration);
138             sasContext.initClient();
139         }
140     }
141
142     public void setContextToken(byte[] contextToken) {
143         this.contextToken = contextToken;
144     }
145
146     public String JavaDoc name()
147     {
148         return name;
149     }
150
151     public void destroy()
152     {
153     }
154
155     public void send_request(org.omg.PortableInterceptor.ClientRequestInfo JavaDoc ri)
156         throws org.omg.PortableInterceptor.ForwardRequest JavaDoc
157     {
158         //if (ri.operation().equals("_is_a")) return;
159
//if (ri.operation().equals("_non_existent")) return;
160
org.omg.CORBA.ORB JavaDoc orb = ((ClientRequestInfoImpl) ri).orb;
161
162         // see if target requires protected requests by looking into the IOR
163
CompoundSecMechList csmList = null;
164         try
165         {
166             TaggedComponent JavaDoc tc = ri.get_effective_component(TAG_CSI_SEC_MECH_LIST.value);
167             CDRInputStream is = new CDRInputStream( (org.omg.CORBA.ORB JavaDoc)null, tc.component_data);
168             is.openEncapsulatedArray();
169             csmList = CompoundSecMechListHelper.read( is );
170         }
171         catch (BAD_PARAM JavaDoc e)
172         {
173             if (logger.isDebugEnabled())
174                 logger.debug("Did not find tagged component TAG_CSI_SEC_MECH_LIST: "+
175                              ri.operation());
176         }
177         catch (Exception JavaDoc e)
178         {
179             if (logger.isWarnEnabled())
180                 logger.warn("Did not find tagged component TAG_CSI_SEC_MECH_LIST: "+e);
181         }
182
183         if(csmList != null &&
184            csmList.mechanism_list[0].as_context_mech.target_supports == 0 &&
185             csmList.mechanism_list[0].as_context_mech.target_requires == 0 &&
186             csmList.mechanism_list[0].sas_context_mech.target_supports == 0 &&
187            csmList.mechanism_list[0].sas_context_mech.target_requires == 0) {
188             return;
189         }
190
191         // ask connection for client_context_id
192
ClientConnection connection = ((ClientRequestInfoImpl) ri).connection;
193
194         long client_context_id = 0;
195         if (useStateful)
196             client_context_id = connection.cacheSASContext("css".getBytes());
197         if (client_context_id < 0)
198         {
199             if (logger.isInfoEnabled())
200                 logger.info("New SAS Context: " + (-client_context_id));
201         }
202
203         // get ATLAS tokens
204
AuthorizationElement[] authorizationList = getATLASTokens(orb, csmList);
205
206         // establish the security context
207
try
208         {
209             Any JavaDoc msg = null;
210             if (client_context_id <= 0)
211             {
212                 IdentityToken identityToken = new IdentityToken();
213                 identityToken.absent(true);
214                 contextToken = sasContext.createClientContext(orb, codec, csmList);
215                 msg = makeEstablishContext(orb,
216                                            -client_context_id,
217                                            authorizationList,
218                                            identityToken,
219                                            contextToken);
220             }
221             else
222             {
223                 msg = makeMessageInContext(orb, client_context_id, false);
224             }
225             ri.add_request_service_context(new ServiceContext JavaDoc(SecurityAttributeService, codec.encode_value( msg ) ), true);
226         }
227         catch (Exception JavaDoc e)
228         {
229             if (logger.isWarnEnabled())
230                 logger.warn("Could not set security service context: " + e);
231             throw new org.omg.CORBA.NO_PERMISSION JavaDoc("SAS Could not set security service context: " + e,
232                                                   MinorCodes.SAS_CSS_FAILURE,
233                                                   CompletionStatus.COMPLETED_NO);
234         }
235     }
236
237     public void send_poll(org.omg.PortableInterceptor.ClientRequestInfo JavaDoc ri)
238     {
239     }
240
241     public void receive_reply(org.omg.PortableInterceptor.ClientRequestInfo JavaDoc ri)
242     {
243         // get SAS message
244
SASContextBody contextBody = null;
245         ServiceContext JavaDoc ctx = null;
246         try
247         {
248             ctx = ri.get_reply_service_context(SecurityAttributeService);
249         }
250         catch (BAD_PARAM JavaDoc e)
251         {
252             if (logger.isDebugEnabled())
253                 logger.debug("No SAS security context found: "+ri.operation());
254         }
255         catch (Exception JavaDoc e)
256         {
257             if (logger.isWarnEnabled())
258                 logger.warn("No SAS security context found: "+e);
259         }
260         if (ctx == null || ctx.context_data.length <= 1) return;
261
262         try
263         {
264             Any JavaDoc msg = codec.decode_value( ctx.context_data, SASContextBodyHelper.type() );
265             contextBody = SASContextBodyHelper.extract(msg);
266         }
267         catch (Exception JavaDoc e)
268         {
269             if (logger.isWarnEnabled())
270                 logger.warn("Could not parse SAS reply: " + e);e.printStackTrace();
271             throw new org.omg.CORBA.NO_PERMISSION JavaDoc("SAS Could not parse SAS reply: " + e,
272                                                   MinorCodes.SAS_CSS_FAILURE,
273                                                   CompletionStatus.COMPLETED_MAYBE);
274         }
275         ClientConnection connection = ((ClientRequestInfoImpl) ri).connection;
276
277         // process CompleteEstablishContext message
278
if (contextBody.discriminator() == MTCompleteEstablishContext.value)
279         {
280             CompleteEstablishContext reply = contextBody.complete_msg();
281
282             // if not stateful, remove from connection
283
if (reply.client_context_id > 0 && !reply.context_stateful)
284                 connection.purgeSASContext(reply.client_context_id);
285         }
286
287         // process ContextError message
288
if (contextBody.discriminator() == MTContextError.value)
289         {
290             ContextError reply = contextBody.error_msg();
291
292             // if stateful, remove from connection
293
if (reply.client_context_id > 0)
294                 connection.purgeSASContext(reply.client_context_id);
295         }
296     }
297
298     public void receive_exception(org.omg.PortableInterceptor.ClientRequestInfo JavaDoc ri)
299         throws org.omg.PortableInterceptor.ForwardRequest JavaDoc
300     {
301         // get SAS message
302
SASContextBody contextBody = null;
303         ServiceContext JavaDoc ctx = null;
304         try
305         {
306             ctx = ri.get_reply_service_context(SecurityAttributeService);
307         }
308         catch (BAD_PARAM JavaDoc e)
309         {
310             if (logger.isDebugEnabled())
311                 logger.debug("No SAS security context found (exception): "+ri.operation());
312         }
313         catch (Exception JavaDoc e)
314         {
315             if (logger.isWarnEnabled())
316                 logger.warn("No SAS security context found (exception): "+e);
317         }
318         if (ctx == null || ctx.context_data.length <= 1) return;
319
320         try
321         {
322             Any JavaDoc msg = codec.decode_value( ctx.context_data, SASContextBodyHelper.type() );
323             contextBody = SASContextBodyHelper.extract(msg);
324         }
325         catch (Exception JavaDoc e)
326         {
327             if (logger.isWarnEnabled())
328                 logger.warn("Could not parse SAS reply: " + e);
329             throw new org.omg.CORBA.NO_PERMISSION JavaDoc("SAS Could not parse SAS reply: " + e,
330                                                   MinorCodes.SAS_CSS_FAILURE,
331                                                   CompletionStatus.COMPLETED_MAYBE);
332         }
333         ClientConnection connection = ((ClientRequestInfoImpl) ri).connection;
334
335         // process CompleteEstablishContext message
336
if (contextBody.discriminator() == MTCompleteEstablishContext.value)
337         {
338             CompleteEstablishContext reply = contextBody.complete_msg();
339             logger.debug("receive_exception MTCompleteEstablishContext: " + reply.client_context_id);
340
341             // if not stateful, remove from connection
342
if (reply.client_context_id > 0 && !reply.context_stateful)
343                 connection.purgeSASContext(reply.client_context_id);
344         }
345
346         // process ContextError message
347
if (contextBody.discriminator() == MTContextError.value)
348         {
349             ContextError reply = contextBody.error_msg();
350             logger.debug("receive_exception MTContextError: " + reply.client_context_id);
351
352             // if stateful, remove from connection
353
if (reply.client_context_id > 0)
354                 connection.purgeSASContext(reply.client_context_id);
355             
356             // if context not found, resend with empty context cache
357
if (reply.major_status == 2) throw new org.omg.PortableInterceptor.ForwardRequest JavaDoc(ri.target());
358         }
359     }
360
361     public void receive_other(org.omg.PortableInterceptor.ClientRequestInfo JavaDoc ri)
362         throws org.omg.PortableInterceptor.ForwardRequest JavaDoc
363     {
364     }
365
366     protected Any JavaDoc makeEstablishContext(org.omg.CORBA.ORB JavaDoc orb,
367                                        long client_context_id,
368                                        AuthorizationElement[] authorization_token,
369                                        IdentityToken identity_token,
370                                        byte[] client_authentication_token)
371     {
372         EstablishContext msg = new EstablishContext();
373         msg.client_context_id = client_context_id;
374         msg.client_authentication_token = client_authentication_token;
375         msg.identity_token = identity_token;
376         msg.authorization_token = authorization_token;
377         SASContextBody contextBody = new SASContextBody();
378         contextBody.establish_msg(msg);
379         Any JavaDoc any = orb.create_any();
380         SASContextBodyHelper.insert( any, contextBody );
381         return any;
382     }
383
384     protected Any JavaDoc makeMessageInContext(org.omg.CORBA.ORB JavaDoc orb,
385                                        long client_context_id,
386                                        boolean discard_context)
387     {
388         MessageInContext msg = new MessageInContext();
389         msg.client_context_id = client_context_id;
390         msg.discard_context = discard_context;
391         SASContextBody contextBody = new SASContextBody();
392         contextBody.in_context_msg(msg);
393         Any JavaDoc any = orb.create_any();
394         SASContextBodyHelper.insert( any, contextBody );
395         return any;
396     }
397
398     protected AuthorizationElement[] getATLASTokens(org.omg.CORBA.ORB JavaDoc orb,
399                                                     CompoundSecMechList csmList)
400         throws org.omg.CORBA.NO_PERMISSION JavaDoc
401     {
402         // find the ATLAS profile in the IOR
403
ATLASProfile atlasProfile = null;
404         try
405         {
406             ServiceConfiguration authorities[] =
407                 csmList.mechanism_list[0].sas_context_mech.privilege_authorities;
408             for (int i = 0; i < authorities.length; i++)
409             {
410                 if (authorities[i].syntax != SCS_ATLAS.value)
411                     continue;
412                 Any JavaDoc any = codec.decode(authorities[i].name);
413                 atlasProfile = ATLASProfileHelper.extract(any);
414             }
415         }
416         catch (Exception JavaDoc e)
417         {
418             if (logger.isWarnEnabled())
419                 logger.warn("Error parsing ATLAS from IOR: " + e);
420             throw new org.omg.CORBA.NO_PERMISSION JavaDoc("SAS Error parsing ATLAS from IOR: " + e,
421                                                   MinorCodes.SAS_ATLAS_FAILURE,
422                                                   CompletionStatus.COMPLETED_NO);
423         }
424         if (atlasProfile == null)
425             return new AuthorizationElement[0];
426
427         String JavaDoc cacheID = new String JavaDoc(atlasProfile.the_cache_id);
428         String JavaDoc locator = atlasProfile.the_locator.the_url();
429         if (locator != null)
430             locator = URLDecoder.decode(locator);
431
432         // see if the tokens are in the ATLAS cache
433
synchronized (atlasCache)
434         {
435             if (atlasCache.containsKey(cacheID))
436             {
437                 return ((AuthTokenData)atlasCache.get(cacheID)).auth_token;
438             }
439         }
440
441         // contact the ATLAS server and get the credentials
442
AuthTokenDispenser dispenser = null;
443         try
444         {
445             org.omg.CORBA.Object JavaDoc obj = orb.string_to_object(locator);
446             dispenser = AuthTokenDispenserHelper.narrow(obj);
447         }
448         catch (Exception JavaDoc e)
449         {
450             logger.warn("Could not find ATLAS server " + locator + ": " + e);
451             throw new org.omg.CORBA.NO_PERMISSION JavaDoc("SAS Could not find ATLAS server " + locator + ": " + e, MinorCodes.SAS_ATLAS_FAILURE, CompletionStatus.COMPLETED_NO);
452         }
453         if (dispenser == null)
454         {
455             if (logger.isWarnEnabled())
456                 logger.warn("SAS found null ATLAS server " + locator);
457             throw new org.omg.CORBA.NO_PERMISSION JavaDoc("SAS found null ATLAS server "+locator,
458                                                   MinorCodes.SAS_ATLAS_FAILURE,
459                                                   CompletionStatus.COMPLETED_NO);
460         }
461
462         AuthTokenData data = null;
463         try
464         {
465             data = dispenser.get_my_authorization_token();
466         }
467         catch (Exception JavaDoc e)
468         {
469             if (logger.isWarnEnabled())
470                 logger.warn("Error getting ATLAS tokens from server " +
471                             locator + ": " + e);
472             throw new org.omg.CORBA.NO_PERMISSION JavaDoc("SAS Error getting ATLAS tokens from server: " + e,
473                                                   MinorCodes.SAS_ATLAS_FAILURE,
474                                                   CompletionStatus.COMPLETED_NO);
475         }
476         synchronized (atlasCache)
477         {
478             atlasCache.put(cacheID, data);
479         }
480         return data.auth_token;
481     }
482
483 }
484
Popular Tags