KickJava   Java API By Example, From Geeks To Geeks.

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


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

24
25 package com.sun.enterprise.iiop.security;
26
27 import java.lang.InheritableThreadLocal JavaDoc;
28 import java.io.IOException JavaDoc;
29 import java.net.Socket JavaDoc;
30 import java.util.Set JavaDoc;
31 import java.util.HashSet JavaDoc;
32 import java.util.Hashtable JavaDoc;
33 import java.util.Iterator JavaDoc;
34 import java.util.Properties JavaDoc;
35 import java.net.InetAddress JavaDoc;
36 import java.util.List JavaDoc;
37 import java.util.ArrayList JavaDoc;
38
39 import java.security.PrivilegedAction JavaDoc;
40 import java.security.AccessController JavaDoc;
41 import javax.security.auth.Subject JavaDoc;
42 import javax.security.auth.login.LoginContext JavaDoc;
43 import java.security.cert.X509Certificate JavaDoc;
44 import javax.net.ssl.SSLSession;
45 import javax.net.ssl.SSLSocket;
46 // GSS Related Functionality
47
import org.ietf.jgss.*;
48
49 import com.sun.enterprise.Switch;
50 import com.sun.enterprise.ExecutionContext;
51 import com.sun.enterprise.InvocationManager;
52 import com.sun.enterprise.InvocationException;
53 import com.sun.enterprise.ComponentInvocation;
54 import com.sun.enterprise.appclient.AppContainer;
55 import com.sun.enterprise.deployment.JndiNameEnvironment;
56 import com.sun.enterprise.deployment.EjbReferenceDescriptor;
57 import com.sun.enterprise.deployment.EjbDescriptor;
58 import com.sun.enterprise.deployment.EjbIORConfigurationDescriptor;
59 import com.sun.enterprise.iiop.CSIV2TaggedComponentInfo;
60 import org.omg.CORBA.ORB JavaDoc;
61 import com.sun.enterprise.iiop.IORToSocketInfoImpl;
62 import com.sun.enterprise.iiop.POAProtocolMgr;
63 import com.sun.enterprise.security.SSLUtils;
64 import com.sun.enterprise.security.auth.login.PasswordCredential;
65 import com.sun.enterprise.security.auth.login.X509CertificateCredential;
66 import com.sun.enterprise.security.auth.LoginContextDriver;
67 import com.sun.enterprise.util.Utility;
68 import com.sun.enterprise.util.ORBManager;
69 import com.sun.enterprise.util.TypeUtil;
70
71 import com.sun.corba.ee.spi.ior.IOR;
72 import com.sun.corba.ee.spi.ior.iiop.IIOPAddress;
73 import com.sun.corba.ee.spi.ior.iiop.IIOPProfileTemplate;
74 import com.sun.corba.ee.spi.transport.SocketInfo;
75 import com.sun.corba.ee.org.omg.CSI.*;
76 import com.sun.corba.ee.org.omg.CSIIOP.*;
77
78 import sun.security.x509.X500Name;
79 import com.sun.enterprise.log.Log;
80 import com.sun.enterprise.util.LocalStringManagerImpl;
81 import java.util.logging.*;
82 import com.sun.logging.*;
83
84 /**
85  * This class is responsible for making various decisions for selecting
86  * security information to be sent in the IIOP message based on target
87  * configuration and client policies.
88  * Note: This class can be called concurrently by multiple client threads.
89  * However, none of its methods need to be synchronized because the methods
90  * either do not modify state or are idempotent.
91  *
92  * @author Vivek Nagar
93  * @author Harpreet Singh
94  * @author Shing Wai Chan
95  */

96
97 public final class SecurityMechanismSelector {
98
99     private static java.util.logging.Logger JavaDoc _logger=null;
100     static{
101        _logger=LogDomains.getLogger(LogDomains.CORBA_LOGGER);
102     }
103
104     public static String JavaDoc CLIENT_CONNECTION_CONTEXT = "ClientConnContext";
105     public static String JavaDoc SERVER_CONNECTION_CONTEXT = "ServerConnContext";
106
107     private static Set JavaDoc corbaIORDescSet = null;
108     private static boolean sslRequired = false;
109
110     // List of hosts trusted by the client for sending passwords to.
111
// Also, list of hosts trusted by the server for accepting propagated
112
// identities.
113
private static String JavaDoc[] serverTrustedHosts = null;
114
115     private static LocalStringManagerImpl localStrings =
116         new LocalStringManagerImpl(SecServerRequestInterceptor.class);
117
118     // A reference to POAProtocolMgr will be obtained dynamically
119
// and set if not null. So set it to null here.
120
private static POAProtocolMgr protocolMgr = null;
121
122     /**
123      * Read the client and server preferences from the config files.
124      */

125     static {
126         try {
127         // Initialize client security config
128
String JavaDoc s =
129         (String JavaDoc)(ORBManager.getCSIv2Props()).get(ORBManager.ORB_SSL_CLIENT_REQUIRED);
130         if ( s != null && s.equals("true") ) {
131         sslRequired = true;
132         }
133
134         // initialize corbaIORDescSet with security config for CORBA objects
135
corbaIORDescSet = new HashSet JavaDoc();
136         EjbIORConfigurationDescriptor iorDesc =
137                         new EjbIORConfigurationDescriptor();
138         EjbIORConfigurationDescriptor iorDesc2 =
139                         new EjbIORConfigurationDescriptor();
140         String JavaDoc serverSslReqd = (String JavaDoc)(ORBManager.getCSIv2Props()).get(ORBManager.ORB_SSL_SERVER_REQUIRED);
141         if ( serverSslReqd != null && serverSslReqd.equals("true") ) {
142         iorDesc.setIntegrity(EjbIORConfigurationDescriptor.REQUIRED);
143         iorDesc.setConfidentiality(
144                     EjbIORConfigurationDescriptor.REQUIRED);
145         iorDesc2.setIntegrity(EjbIORConfigurationDescriptor.REQUIRED);
146         iorDesc2.setConfidentiality(
147                     EjbIORConfigurationDescriptor.REQUIRED);
148         }
149         String JavaDoc clientAuthReq =
150         (String JavaDoc)(ORBManager.getCSIv2Props()).get(ORBManager.ORB_CLIENT_AUTH_REQUIRED);
151         if ( clientAuthReq != null && clientAuthReq.equals("true") ) {
152         // Need auth either by SSL or username-password.
153
// This sets SSL clientauth to required.
154
iorDesc.setEstablishTrustInClient(
155                     EjbIORConfigurationDescriptor.REQUIRED);
156         // This sets username-password auth to required.
157
iorDesc2.setAuthMethodRequired(true);
158         corbaIORDescSet.add(iorDesc2);
159         }
160         corbaIORDescSet.add(iorDesc);
161         
162         } catch(Exception JavaDoc e) {
163             _logger.log(Level.SEVERE,"iiop.Exception",e);
164         }
165     }
166
167     private CompoundSecMech mechanism = null;
168     private ORB JavaDoc orb = null;
169     private CSIV2TaggedComponentInfo ctc = null;
170
171     /**
172      * Default constructor.
173      */

174     public SecurityMechanismSelector() {
175         this.orb = ORBManager.getORB();
176         this.ctc = new CSIV2TaggedComponentInfo(orb);
177     }
178
179     public static ServerConnectionContext getServerConnectionContext() {
180         Hashtable JavaDoc h = ConnectionExecutionContext.getContext();
181         ServerConnectionContext scc =
182             (ServerConnectionContext) h.get(SERVER_CONNECTION_CONTEXT);
183         return scc;
184     }
185
186     public static void setServerConnectionContext(ServerConnectionContext scc) {
187         Hashtable JavaDoc h = ConnectionExecutionContext.getContext();
188         h.put(SERVER_CONNECTION_CONTEXT, scc);
189     }
190
191     public ConnectionContext getClientConnectionContext() {
192         Hashtable JavaDoc h = ConnectionExecutionContext.getContext();
193         ConnectionContext scc =
194             (ConnectionContext) h.get(CLIENT_CONNECTION_CONTEXT);
195         return scc;
196     }
197
198     public void setClientConnectionContext(ConnectionContext scc) {
199         Hashtable JavaDoc h = ConnectionExecutionContext.getContext();
200         h.put(CLIENT_CONNECTION_CONTEXT, scc);
201     }
202
203     /**
204      * This method determines if SSL should be used to connect to the
205      * target based on client and target policies. It will return null if
206      * SSL should not be used or an SocketInfo containing the SSL port
207      * if SSL should be used.
208      */

209     public SocketInfo getSSLPort(IOR ior, ConnectionContext ctx)
210     {
211         SocketInfo info = null;
212         try {
213             mechanism = selectSecurityMechanism(ior);
214         } catch(SecurityMechanismException sme) {
215             throw new RuntimeException JavaDoc(sme.getMessage());
216         }
217         ctx.setIOR(ior);
218         ctx.setMechanism(mechanism);
219
220         TLS_SEC_TRANS ssl = null;
221         if ( mechanism != null ) {
222             ssl = ctc.getSSLInformation(mechanism);
223         }
224
225         if (ssl == null) {
226             if (sslRequired) {
227                 // Attempt to create SSL connection to host, ORBInitialPort
228
IIOPProfileTemplate templ = (IIOPProfileTemplate)
229                     ior.getProfile().getTaggedProfileTemplate();
230                 IIOPAddress addr = templ.getPrimaryAddress();
231                 info = IORToSocketInfoImpl.createSocketInfo(
232                 "SecurityMechanismSelector1",
233                         "SSL", addr.getHost(), ORBManager.getORBInitialPort());
234                 return info;
235             } else {
236                 return null;
237             }
238         }
239
240         int targetRequires = ssl.target_requires;
241         int targetSupports = ssl.target_supports;
242         
243         /*
244          * If target requires any of Integrity, Confidentiality or
245          * EstablishTrustInClient, then SSL is used.
246          */

247         if (isSet(targetRequires, Integrity.value) ||
248                 isSet(targetRequires, Confidentiality.value) ||
249                 isSet(targetRequires, EstablishTrustInClient.value)) {
250             if (_logger.isLoggable(Level.FINE)) {
251                  _logger.log(Level.FINE, "Target requires SSL");
252             }
253             ctx.setSSLUsed(true);
254             String JavaDoc type = "SSL";
255             if(isSet(targetRequires, EstablishTrustInClient.value)) {
256                 type = "SSL_MUTUALAUTH";
257                 ctx.setSSLClientAuthenticationOccurred(true);
258             }
259             short sslport = ssl.addresses[0].port;
260             int ssl_port = Utility.shortToInt(sslport);
261             String JavaDoc host_name = ssl.addresses[0].host_name;
262             
263             info = IORToSocketInfoImpl.createSocketInfo(
264             "SecurityMechanismSelector2",
265                     type, host_name, ssl_port);
266
267             return info;
268         } else if (isSet(targetSupports, Integrity.value) ||
269                     isSet(targetSupports, Confidentiality.value) ||
270                     isSet(targetSupports, EstablishTrustInClient.value)) {
271             if (_logger.isLoggable(Level.FINE)) {
272                 _logger.log(Level.FINE, "Target supports SSL");
273             }
274
275             if ( sslRequired ) {
276                 if (_logger.isLoggable(Level.FINE)) {
277                     _logger.log(Level.FINE, "Client is configured to require SSL for the target");
278                 }
279
280                 ctx.setSSLUsed(true);
281                 short sslport = ssl.addresses[0].port;
282                 String JavaDoc host_name = ssl.addresses[0].host_name;
283                 int ssl_port = Utility.shortToInt(sslport);
284                 info = IORToSocketInfoImpl.createSocketInfo(
285                 "SecurityMechanismSelector3",
286                         "SSL", host_name, ssl_port);
287                 return info;
288             } else {
289                 return null;
290             }
291         } else if ( sslRequired ) {
292         throw new RuntimeException JavaDoc("SSL required by client but not supported by server.");
293     } else {
294         return null;
295     }
296     }
297     
298     public Logger get_logger() {
299         return _logger;
300     }
301     
302     public void set_logger(Logger val) {
303         this._logger = val;
304     }
305     
306     public String JavaDoc getCLIENT_CONNECTION_CONTEXT() {
307         return CLIENT_CONNECTION_CONTEXT;
308     }
309     
310     public void setCLIENT_CONNECTION_CONTEXT(String JavaDoc val) {
311         this.CLIENT_CONNECTION_CONTEXT = val;
312     }
313     
314     public String JavaDoc getSERVER_CONNECTION_CONTEXT() {
315         return SERVER_CONNECTION_CONTEXT;
316     }
317     
318     public void setSERVER_CONNECTION_CONTEXT(String JavaDoc val) {
319         this.SERVER_CONNECTION_CONTEXT = val;
320     }
321     
322     public Set JavaDoc getCorbaIORDescSet() {
323         return corbaIORDescSet;
324     }
325     
326     public void setCorbaIORDescSet(Set JavaDoc val) {
327         this.corbaIORDescSet = val;
328     }
329     
330     public boolean getSslRequired() {
331         return sslRequired;
332     }
333     
334     public void setSslRequired(boolean val) {
335         this.sslRequired = val;
336     }
337     
338     public String JavaDoc[] getServerTrustedHosts() {
339         return serverTrustedHosts;
340     }
341     
342     public void setServerTrustedHosts(String JavaDoc[] val) {
343         this.serverTrustedHosts = val;
344     }
345     
346     public LocalStringManagerImpl getLocalStrings() {
347         return localStrings;
348     }
349     
350     public void setLocalStrings(LocalStringManagerImpl val) {
351         this.localStrings = val;
352     }
353     
354     public POAProtocolMgr getProtocolMgr() {
355         return protocolMgr;
356     }
357     
358     public void setProtocolMgr(POAProtocolMgr val) {
359         this.protocolMgr = val;
360     }
361     
362     public CompoundSecMech getMechanism() {
363         return mechanism;
364     }
365     
366     public void setMechanism(CompoundSecMech val) {
367         this.mechanism = val;
368     }
369     
370     public ORB JavaDoc getOrb() {
371         return orb;
372     }
373     
374     public void setOrb(ORB JavaDoc val) {
375         this.orb = val;
376     }
377     
378     public CSIV2TaggedComponentInfo getCtc() {
379         return ctc;
380     }
381     
382     public void setCtc(CSIV2TaggedComponentInfo val) {
383         this.ctc = val;
384     }
385     
386     public java.util.List JavaDoc<SocketInfo> getSSLPorts(IOR ior, ConnectionContext ctx)
387     {
388         try {
389             mechanism = selectSecurityMechanism(ior);
390         } catch(SecurityMechanismException sme) {
391             throw new RuntimeException JavaDoc(sme.getMessage());
392         }
393         ctx.setIOR(ior);
394         ctx.setMechanism(mechanism);
395
396         TLS_SEC_TRANS ssl = null;
397         if ( mechanism != null ) {
398             ssl = ctc.getSSLInformation(mechanism);
399         }
400
401         if (ssl == null) {
402             if (sslRequired) {
403                 // Attempt to create SSL connection to host, ORBInitialPort
404
IIOPProfileTemplate templ = (IIOPProfileTemplate)
405                     ior.getProfile().getTaggedProfileTemplate();
406                 IIOPAddress addr = templ.getPrimaryAddress();
407                 SocketInfo info = IORToSocketInfoImpl.createSocketInfo(
408                 "SecurityMechanismSelector1",
409                         "SSL", addr.getHost(), ORBManager.getORBInitialPort());
410                 //SocketInfo[] sInfos = new SocketInfo[]{info};
411
List JavaDoc<SocketInfo> sInfos = new ArrayList JavaDoc<SocketInfo>();
412                 sInfos.add(info);
413                 return sInfos;
414             } else {
415                 return null;
416             }
417         }
418
419         int targetRequires = ssl.target_requires;
420         int targetSupports = ssl.target_supports;
421         
422         /*
423          * If target requires any of Integrity, Confidentiality or
424          * EstablishTrustInClient, then SSL is used.
425          */

426         if (isSet(targetRequires, Integrity.value) ||
427                 isSet(targetRequires, Confidentiality.value) ||
428                 isSet(targetRequires, EstablishTrustInClient.value)) {
429             if (_logger.isLoggable(Level.FINE)) {
430                  _logger.log(Level.FINE, "Target requires SSL");
431             }
432             ctx.setSSLUsed(true);
433             String JavaDoc type = "SSL";
434             if(isSet(targetRequires, EstablishTrustInClient.value)) {
435                 type = "SSL_MUTUALAUTH";
436                 ctx.setSSLClientAuthenticationOccurred(true);
437             }
438             //SocketInfo[] socketInfos = new SocketInfo[ssl.addresses.size];
439
List JavaDoc<SocketInfo> socketInfos = new ArrayList JavaDoc<SocketInfo>();
440             for(int addressIndex =0; addressIndex < ssl.addresses.length; addressIndex++){
441                 short sslport = ssl.addresses[addressIndex].port;
442                 int ssl_port = Utility.shortToInt(sslport);
443                 String JavaDoc host_name = ssl.addresses[addressIndex].host_name;
444             
445                 SocketInfo sInfo = IORToSocketInfoImpl.createSocketInfo(
446             "SecurityMechanismSelector2",
447                     type, host_name, ssl_port);
448                 socketInfos.add(sInfo);
449             }
450             return socketInfos;
451         } else if (isSet(targetSupports, Integrity.value) ||
452                     isSet(targetSupports, Confidentiality.value) ||
453                     isSet(targetSupports, EstablishTrustInClient.value)) {
454             if (_logger.isLoggable(Level.FINE)) {
455                 _logger.log(Level.FINE, "Target supports SSL");
456             }
457
458             if ( sslRequired ) {
459                 if (_logger.isLoggable(Level.FINE)) {
460                     _logger.log(Level.FINE, "Client is configured to require SSL for the target");
461                 }
462
463                 ctx.setSSLUsed(true);
464                 //SocketInfo[] socketInfos = new SocketInfo[ssl.addresses.size];
465
List JavaDoc<SocketInfo> socketInfos = new ArrayList JavaDoc<SocketInfo>();
466                 for(int addressIndex =0; addressIndex < ssl.addresses.length; addressIndex++){
467                     short sslport = ssl.addresses[addressIndex].port;
468                     int ssl_port = Utility.shortToInt(sslport);
469                     String JavaDoc host_name = ssl.addresses[addressIndex].host_name;
470
471                     SocketInfo sInfo = IORToSocketInfoImpl.createSocketInfo(
472                         "SecurityMechanismSelector3",
473                         "SSL", host_name, ssl_port);
474                     socketInfos.add(sInfo);
475                 }
476                 return socketInfos;
477             } else {
478                 return null;
479             }
480         } else if ( sslRequired ) {
481         throw new RuntimeException JavaDoc("SSL required by client but not supported by server.");
482     } else {
483         return null;
484     }
485     }
486
487
488     /**
489      * Select the security context to be used by the CSIV2 layer
490      * based on whether the current component is an application
491      * client or a web/EJB component.
492      */

493
494     public SecurityContext selectSecurityContext(IOR ior)
495         throws InvalidIdentityTokenException,
496             InvalidMechanismException, SecurityMechanismException
497     {
498         SecurityContext context = null;
499         ConnectionContext cc = getClientConnectionContext();
500         if(cc == null) {
501             return null;
502         }
503         mechanism = cc.getMechanism();
504         if(mechanism == null) {
505             return null;
506         }
507         boolean sslUsed = cc.getSSLUsed();
508         boolean clientAuthOccurred = cc.getSSLClientAuthenticationOccurred();
509         InvocationManager im = Switch.getSwitch().getInvocationManager();
510         if(im == null) {
511             // Standalone client
512
context = getSecurityContextForAppClient(null, sslUsed,
513 clientAuthOccurred);
514             return context;
515         }
516
517         if (_logger.isLoggable(Level.FINE)) {
518             _logger.log(Level.FINE, "SSL used:" + sslUsed + " SSL Mutual auth:" + clientAuthOccurred);
519         }
520
521         ComponentInvocation ci = null;
522         // BEGIN IASRI# 4646060
523
ci = im.getCurrentInvocation();
524         if (ci == null) {
525         // END IASRI# 4646060
526
return null;
527         }
528         Object JavaDoc obj = ci.getContainerContext();
529         if(obj instanceof AppContainer) {
530             context = getSecurityContextForAppClient(ci, sslUsed, clientAuthOccurred);
531         } else {
532             context = getSecurityContextForWebOrEJB(ci, sslUsed, clientAuthOccurred);
533         }
534         return context;
535     }
536
537     /**
538      * Create the security context to be used by the CSIV2 layer
539      * to marshal in the service context of the IIOP message from an appclient
540      * or standalone client.
541      * @return the security context.
542      */

543     public SecurityContext getSecurityContextForAppClient(
544                                         ComponentInvocation ci,
545                                         boolean sslUsed,
546                                         boolean clientAuthOccurred)
547         throws InvalidMechanismException, InvalidIdentityTokenException,
548                                             SecurityMechanismException {
549
550         return sendUsernameAndPassword(ci, sslUsed, clientAuthOccurred);
551     }
552
553     /**
554      * Create the security context to be used by the CSIV2 layer
555      * to marshal in the service context of the IIOP message from an web
556      * component or EJB invoking another EJB.
557      * @return the security context.
558      */

559     public SecurityContext getSecurityContextForWebOrEJB(
560                         ComponentInvocation ci, boolean sslUsed,
561                         boolean clientAuthOccurred)
562         throws InvalidMechanismException, InvalidIdentityTokenException,
563                             SecurityMechanismException {
564
565         SecurityContext ctx = null;
566         if(!sslUsed) {
567         ctx = propagateIdentity(false, ci);
568     } else {
569         ctx = propagateIdentity(clientAuthOccurred, ci);
570     }
571     return ctx;
572     }
573
574     private boolean isMechanismSupported(SAS_ContextSec sas){
575         byte[][] mechanisms = sas.supported_naming_mechanisms;
576         byte[] mechSupported = {};
577         try{
578             mechSupported = GSSUtils.getDER(GSSUtils.GSSUP_MECH_OID);
579         } catch (Exception JavaDoc e){
580             // think what to do with the exception
581
// dont see why it would be thrown
582
return false;
583         }
584         if (mechanisms[0].length != mechSupported.length)
585             return false;
586         for (int i=0; i<mechanisms[0].length; i++){
587             if (mechanisms[0][i] != mechSupported[i])
588                 return false;
589         }
590         return true;
591     }
592     public boolean isIdentityTypeSupported(SAS_ContextSec sas){
593         int ident_token = sas.supported_identity_types;
594         // the identity token matches atleast one of the types we support
595
int value = ident_token &
596             CSIV2TaggedComponentInfo.SUPPORTED_IDENTITY_TOKEN_TYPES;
597         if (value != 0)
598             return true;
599         else
600             return false;
601     }
602
603     /**
604      * Get the security context to send username and password in the
605      * service context.
606      * @param whether username/password will be sent over plain IIOP or
607      * over IIOP/SSL.
608      * @return the security context.
609      * @exception SecurityMechanismException if there was an error.
610      */

611     private SecurityContext sendUsernameAndPassword(ComponentInvocation ci,
612                             boolean sslUsed,
613                             boolean clientAuthOccurred)
614                 throws SecurityMechanismException {
615         SecurityContext ctx = null;
616         if(mechanism == null) {
617             return null;
618         }
619         AS_ContextSec asContext = mechanism.as_context_mech;
620         if( isSet(asContext.target_requires, EstablishTrustInClient.value)
621             || ( isSet(mechanism.target_requires, EstablishTrustInClient.value)
622          && !clientAuthOccurred ) ) {
623
624             ctx = getUsernameAndPassword(ci);
625
626             if (_logger.isLoggable(Level.FINE)) {
627                 _logger.log(Level.FINE, "Sending Username/Password");
628             }
629         } else {
630             return null;
631         }
632         return ctx;
633     }
634
635     /**
636      * Get the security context to propagate principal/distinguished name
637      * in the service context.
638      * @param clientAuth whether SSL client authentication has happened.
639      * @return the security context.
640      * @exception SecurityMechanismException if there was an error.
641      */

642     private SecurityContext propagateIdentity(boolean clientAuth,
643                                               ComponentInvocation ci)
644         throws InvalidIdentityTokenException, InvalidMechanismException,
645 SecurityMechanismException {
646             
647         SecurityContext ctx = null;
648         if(mechanism == null) {
649             return null;
650         }
651         AS_ContextSec asContext = mechanism.as_context_mech;
652         SAS_ContextSec sasContext = mechanism.sas_context_mech;
653         if (_logger.isLoggable(Level.FINE)) {
654             _logger.log(Level.FINE, "SAS CONTEXT's target_requires=" + sasContext.target_requires);
655             _logger.log(Level.FINE, "SAS CONTEXT's target_supports=" + sasContext.target_supports);
656         }
657
658         if(isSet(asContext.target_requires, EstablishTrustInClient.value)) {
659             ctx = getUsernameAndPassword(ci);
660             if (ctx.authcls == null){ // run as mode cannot send password
661
String JavaDoc errmsg =
662 localStrings.getLocalString("securitymechansimselector.runas_cannot_propagate_username_password",
663 "Cannot propagate username/password required by target when using run as identity");
664
665             _logger.log(Level.SEVERE,"iiop.runas_error",errmsg);
666             throw new SecurityMechanismException (errmsg);
667             }
668         } else if(isSet(sasContext.target_supports, IdentityAssertion.value) ||
669                   isSet(sasContext.target_requires, IdentityAssertion.value)) {
670             // called from the client side. thus before getting the identity. check the
671
// mechanisms and the identity token supported
672
if(!isIdentityTypeSupported(sasContext)){
673                 String JavaDoc errmsg =
674                     localStrings.getLocalString("securitymechanismselector.invalid_identity_type",
675                                                 "The given identity token is unsupported.");
676                 throw new InvalidIdentityTokenException(errmsg);
677             }
678             if (sasContext.target_supports == IdentityAssertion.value){
679                 if(!isMechanismSupported(sasContext)){
680                     String JavaDoc errmsg =
681                         localStrings.getLocalString("securitymechanismselector.invalid_mechanism",
682                                                     "The given mechanism type is unsupported.");
683                 _logger.log(Level.SEVERE,"iiop.unsupported_type_error",errmsg);
684                 throw new InvalidMechanismException(errmsg);
685                 }
686             }
687
688             // propagate principal/certificate/distinguished name
689
ctx = getIdentity();
690         } else if(isSet(asContext.target_supports,
691                         EstablishTrustInClient.value)) {
692             if (clientAuth) { // client auth done we can send password
693
ctx = getUsernameAndPassword(ci);
694                 if (ctx.authcls == null) {
695                     return null; // runas mode dont have username/password
696
// dont really need to send it too
697
}
698             } else { // not sending anything for unauthenticated client
699
return null;
700             }
701         } else{
702             return null; // will never come here
703
}
704         return ctx;
705     }
706
707
708     /**
709      * Return whether the server is trusted or not based on configuration
710      * information.
711      * @return true if the server is trusted.
712      */

713     private boolean isServerTrusted() {
714         String JavaDoc star = "*";
715         // first check if "*" in trusted - then why bother
716
// doing all the processing . We trust everything
717
// System.out.println (" In server trusted ??");
718
for (int i = 0; i < serverTrustedHosts.length; i++){
719             if (serverTrustedHosts[i].length () == 1) {
720                 if (serverTrustedHosts[i].equals (star))
721                     return true;
722             }
723         }
724         ConnectionContext scc = getClientConnectionContext ();
725         if (scc != null){
726             Socket JavaDoc skt = scc.getSocket ();
727             InetAddress JavaDoc adr = skt.getInetAddress ();
728             // System.out.println (" Calling isServerTrusted");
729
// System.out.println (" addres "+ adr.toString ());
730
return isDomainInTrustedList (adr, serverTrustedHosts);
731         }
732         return false;
733
734     }
735
736     /**
737      * Checks if a given domain is trusted.
738      * e.g. domain = 123.203.1.1 is an IP address
739      * trusted list = *.com, *.eng
740      * should say that the given domain is trusted.
741      * @param the InetAddress of the domain to be checked for
742      * @param the array of trusted domains
743      * @return true - if the given domain is trusted
744      */

745     private boolean isDomainInTrustedList (InetAddress JavaDoc inetAddress,
746                                            String JavaDoc[] trusted)
747         throws SecurityException JavaDoc
748     {
749         boolean isTrusted = false;
750         String JavaDoc domain = null;
751         String JavaDoc star = "*";
752         String JavaDoc dot = ".";
753         // lookup and get domain name
754
try{
755             domain = inetAddress.getHostName ();
756         } catch (Exception JavaDoc e){
757             _logger.log(Level.SEVERE,"iiop.domain_lookup_failed",inetAddress.getHostAddress ());
758             return false;
759         }
760         if (_logger.isLoggable(Level.FINE)) {
761             _logger.log(Level.FINE, " Verifying if domain address ="+
762                  inetAddress.toString () + " is in the Trusted list ");
763             _logger.log(Level.FINE, " the domain name is = "+ domain);
764         }
765
766         String JavaDoc[] domainTok = TypeUtil.stringToArray (domain, dot);
767         // now lets go through the list of trusted domains
768
// one at a time
769
for (int i=0; i< trusted.length; i++){
770             // String to compare with
771
String JavaDoc[] toksList =
772                 TypeUtil.stringToArray (trusted[i], dot);
773             // cannot compare *.eng to *.eng.sun
774
if (toksList.length != domainTok.length){
775                 isTrusted = false;
776                 continue;
777             } else{
778                 for (int j=toksList.length-1; j>=0 ; j--){
779                     // compare com in *.eng.com and abc.eng.com
780
// compare in the reverse order
781
if (toksList[j].equals (domainTok[j])){
782                         isTrusted = true;
783                     } else {
784                         // compare * in abc.*.com and abc.eng.com
785
if (toksList[j].equals (star)){
786                             isTrusted = true;
787                         }
788                         else {
789                             // get out and try the next domain
790
isTrusted = false;
791                             break;
792                         }
793                     }
794                 }
795                 // We went through one domain and found a match
796
// no need to compare further
797
if (isTrusted)
798                     return isTrusted;
799             }
800         }
801         return isTrusted;
802     }
803
804
805     /**
806      * Get the username and password either from the JAAS subject or
807      * from thread local storage. For appclients if login has'nt happened
808      * this method would trigger login and popup a user interface to
809      * gather authentication information.
810      * @return the security context.
811      */

812     private SecurityContext getUsernameAndPassword(ComponentInvocation ci)
813             throws SecurityMechanismException {
814         try {
815             Subject JavaDoc s = null;
816             if(ci == null) {
817         // Standalone client ... Changed the security context
818
// from which to fetch the subject
819
com.sun.enterprise.security.ClientSecurityContext sc =
820                     com.sun.enterprise.security.ClientSecurityContext.getCurrent();
821                 if(sc == null) {
822                     return null;
823                 }
824                 s = sc.getSubject();
825                 if (_logger.isLoggable(Level.FINE)) {
826                     _logger.log(Level.FINE, "SUBJECT:" + s);
827                 }
828             } else {
829                 Object JavaDoc obj = ci.getContainerContext();
830                 if(obj instanceof AppContainer) {
831             // get the subject
832
com.sun.enterprise.security.ClientSecurityContext sc =
833                         com.sun.enterprise.security.ClientSecurityContext.getCurrent();
834                     if(sc == null) {
835             s = LoginContextDriver.doClientLogin(
836                                 AppContainer.USERNAME_PASSWORD,
837                                 AppContainer.getCallbackHandler());
838                     } else {
839                         s = sc.getSubject();
840                     }
841                 } else {
842                     // web/ejb
843
s = getSubjectFromSecurityCurrent();
844                     // TODO check if username/password is available
845
// if not throw exception
846
}
847             }
848             SecurityContext ctx = new SecurityContext();
849             final Subject JavaDoc sub = s;
850             ctx.subject = s;
851             // determining if run-as has been used
852
Set JavaDoc privateCredSet =
853                 (Set JavaDoc) AccessController.doPrivileged(new PrivilegedAction JavaDoc() {
854                     public java.lang.Object JavaDoc run() {
855                         return sub.getPrivateCredentials();
856                     }
857                 });
858             if (privateCredSet.isEmpty()) { // this is runas case dont set
859
if (_logger.isLoggable(Level.FINE)) {
860                     _logger.log(Level.FINE, "no private credential run as mode");
861                 }
862                 ctx.authcls = null; // the auth class
863
ctx.identcls = GSSUPName.class;
864                 
865             } else{
866                 /** lookup the realm name that is required by the server
867                  * and set it up in the PasswordCredential class.
868                  */

869                 AS_ContextSec asContext = mechanism.as_context_mech;
870                 final byte[] target_name = asContext.target_name;
871                 byte[] _realm = GSSUtils.importName(GSSUtils.GSSUP_MECH_OID, target_name);
872                 final String JavaDoc realm_name = new String JavaDoc(_realm);
873                 final Iterator JavaDoc it = privateCredSet.iterator();
874                 for(;it.hasNext();){
875                     AccessController.doPrivileged(new PrivilegedAction JavaDoc(){
876                         public java.lang.Object JavaDoc run(){
877                             PasswordCredential pc = (PasswordCredential) it.next();
878                             pc.setRealm(realm_name);
879                             return null;
880                         }
881                     });
882                 }
883                 ctx.authcls = PasswordCredential.class;
884             }
885             return ctx;
886         } catch(Exception JavaDoc e) {
887             _logger.log(Level.SEVERE,"iiop.user_password_exception",e);
888             return null;
889         }
890     }
891
892     /**
893      * Get the principal/distinguished name from thread local storage.
894      * @return the security context.
895      */

896     private SecurityContext getIdentity()
897             throws SecurityMechanismException {
898         if (_logger.isLoggable(Level.FINE)) {
899             _logger.log(Level.FINE, "Getting PRINCIPAL/DN from TLS");
900         }
901
902         SecurityContext ctx = new SecurityContext();
903         final SecurityContext sCtx = ctx;
904     // get stuff from the SecurityContext class
905
com.sun.enterprise.security.SecurityContext scontext =
906             com.sun.enterprise.security.SecurityContext.getCurrent();
907         if ((scontext == null) ||
908              scontext.didServerGenerateCredentials()){
909             
910             // a default guest/guest123 was created
911
sCtx.identcls = AnonCredential.class;
912             
913             AccessController.doPrivileged(new PrivilegedAction JavaDoc() {
914                 public java.lang.Object JavaDoc run(){
915                     // remove all the public and private credentials
916
Subject JavaDoc sub = new Subject JavaDoc();
917                     sCtx.subject = sub;
918                     sCtx.subject.getPublicCredentials().add(new AnonCredential());
919                     return null;
920                 }
921             });
922             return sCtx;
923         }
924
925         Subject JavaDoc s = getSubjectFromSecurityCurrent();
926         ctx.subject = s;
927
928         // Figure out the credential class
929
final Subject JavaDoc sub = s;
930         Set JavaDoc credSet =
931             (Set JavaDoc) AccessController.doPrivileged(new PrivilegedAction JavaDoc() {
932                 public java.lang.Object JavaDoc run() {
933                     return sub.getPrivateCredentials(PasswordCredential.class);
934                 }
935             });
936         if(credSet.size() == 1) {
937             ctx.identcls = GSSUPName.class;
938             final Set JavaDoc cs = credSet;
939             Subject JavaDoc subj = (Subject JavaDoc) AccessController.doPrivileged(new
940             PrivilegedAction JavaDoc() {
941                 public java.lang.Object JavaDoc run() {
942                     Subject JavaDoc ss = new Subject JavaDoc();
943                     Iterator JavaDoc iter = cs.iterator();
944                     PasswordCredential pc = (PasswordCredential) iter.next();
945                     GSSUPName gssname = new GSSUPName(pc.getUser(), pc.getRealm());
946                     ss.getPublicCredentials().add(gssname);
947                     return ss;
948                 }
949             });
950             ctx.subject = subj;
951             return ctx;
952         }
953
954         credSet = s.getPublicCredentials();
955         if(credSet.size() != 1) {
956             _logger.log(Level.SEVERE,"iiop.principal_error");
957             return null;
958         } else {
959             Iterator JavaDoc credIter = credSet.iterator();
960             if(credIter.hasNext()) {
961                 Object JavaDoc o = credIter.next();
962                 if(o instanceof GSSUPName) {
963                     ctx.identcls = GSSUPName.class;
964                 } else if(o instanceof X500Name) {
965                     ctx.identcls = X500Name.class;
966                 } else {
967                     ctx.identcls = X509CertificateCredential.class;
968                 }
969             } else {
970             _logger.log(Level.SEVERE,"iiop.credential_error");
971                 return null;
972             }
973         }
974         return ctx;
975     }
976
977     private Subject JavaDoc getSubjectFromSecurityCurrent()
978             throws SecurityMechanismException {
979         com.sun.enterprise.security.SecurityContext sc = null;
980         sc = com.sun.enterprise.security.SecurityContext.getCurrent();
981         if(sc == null) {
982             if(_logger.isLoggable(Level.FINE)) {
983             _logger.log(Level.FINE," SETTING GUEST ---");
984             }
985             sc = com.sun.enterprise.security.SecurityContext.init();
986         }
987         if(sc == null) {
988             throw new SecurityMechanismException("Could not find " +
989                         " security information");
990         }
991         Subject JavaDoc s = sc.getSubject();
992         if(s == null) {
993             throw new SecurityMechanismException("Could not find " +
994                 " subject information in the security context.");
995         }
996         if (_logger.isLoggable(Level.FINE)) {
997             _logger.log(Level.FINE, "Subject in security current:" + s);
998         }
999         return s;
1000    }
1001
1002    public CompoundSecMech selectSecurityMechanism(IOR ior)
1003            throws SecurityMechanismException {
1004        CompoundSecMech[] mechList = ctc.getSecurityMechanisms(ior);
1005        CompoundSecMech mech = selectSecurityMechanism(mechList);
1006        return mech;
1007    }
1008
1009    /**
1010     * Select the security mechanism from the list of compound security
1011     * mechanisms.
1012     */

1013    private CompoundSecMech selectSecurityMechanism(
1014                CompoundSecMech[] mechList) throws SecurityMechanismException {
1015        // We should choose from list of compound security mechanisms
1016
// which are in decreasing preference order. Right now we select
1017
// the first one.
1018
if(mechList == null || mechList.length == 0) {
1019            return null;
1020        }
1021        CompoundSecMech mech = null;
1022        for(int i = 0; i < mechList.length; i++) {
1023            mech = mechList[i];
1024            boolean useMech = useMechanism(mech);
1025            if(useMech) {
1026                return mech;
1027            }
1028        }
1029        throw new SecurityMechanismException("Cannot use any of the " +
1030            " target's supported mechanisms");
1031    }
1032
1033    private boolean useMechanism(CompoundSecMech mech) {
1034        boolean val = true;
1035        TLS_SEC_TRANS tls = ctc.getSSLInformation(mech);
1036
1037        if(tls == null) {
1038            return true;
1039        }
1040        int targetRequires = tls.target_requires;
1041        if(isSet(targetRequires, EstablishTrustInClient.value)) {
1042            if(! SSLUtils.isKeyAvailable()) {
1043                val = false;
1044            }
1045        }
1046        return val;
1047    }
1048
1049    // Returns the target_name from PasswordCredential in Subject subj
1050
// subj must contain a single instance of PasswordCredential.
1051

1052    private byte[] getTargetName(Subject JavaDoc subj)
1053    {
1054  
1055        byte[] tgt_name = {} ;
1056
1057        final Subject JavaDoc sub = subj;
1058        final Set JavaDoc credset =
1059            (Set JavaDoc) AccessController.doPrivileged(new PrivilegedAction JavaDoc() {
1060                public java.lang.Object JavaDoc run() {
1061                    return sub.getPrivateCredentials(PasswordCredential.class);
1062                }
1063            });
1064        if(credset.size() == 1) {
1065            tgt_name = (byte[]) AccessController.doPrivileged(new PrivilegedAction JavaDoc() {
1066                public java.lang.Object JavaDoc run() {
1067                    Iterator JavaDoc iter = credset.iterator();
1068                    PasswordCredential pc = (PasswordCredential) iter.next();
1069                    return pc.getTargetName();
1070                }
1071            });
1072        }
1073        return tgt_name;
1074    }
1075
1076    private boolean evaluate_client_conformance_ssl(
1077                        EjbIORConfigurationDescriptor iordesc,
1078                        boolean ssl_used,
1079                        X509Certificate JavaDoc[] certchain)
1080    {
1081      try {
1082        if(_logger.isLoggable(Level.FINE)) {
1083        _logger.log(Level.FINE,
1084            "SecurityMechanismSelector.evaluate_client_conformance_ssl->:");
1085    }
1086    
1087        boolean ssl_required = false;
1088        boolean ssl_supported = false;
1089        int ssl_target_requires = 0;
1090        int ssl_target_supports = 0;
1091
1092        /*************************************************************************
1093         * Conformance Matrix:
1094         *
1095         * |---------------|---------------------|---------------------|------------|
1096         * | SSLClientAuth | targetrequires.ETIC | targetSupports.ETIC | Conformant |
1097         * |---------------|---------------------|---------------------|------------|
1098         * | Yes | 0 | 1 | Yes |
1099         * | Yes | 0 | 0 | No |
1100         * | Yes | 1 | X | Yes |
1101         * | No | 0 | X | Yes |
1102         * | No | 1 | X | No |
1103         * |---------------|---------------------|---------------------|------------|
1104         *
1105         *************************************************************************/

1106
1107        // gather the configured SSL security policies.
1108

1109        ssl_target_requires = this.ctc.getTargetRequires(iordesc);
1110        ssl_target_supports = this.ctc.getTargetSupports(iordesc);
1111
1112        if ( isSet(ssl_target_requires, Integrity.value)
1113             || isSet(ssl_target_requires, Confidentiality.value)
1114             || isSet(ssl_target_requires, EstablishTrustInClient.value))
1115            ssl_required = true;
1116        else
1117            ssl_required = false;
1118
1119        if ( ssl_target_supports != 0)
1120            ssl_supported = true;
1121        else
1122            ssl_supported = false;
1123
1124        /* Check for conformance for using SSL usage.
1125         *
1126         * a. if SSL was used, then either the target must require or support
1127         * SSL. In the latter case, SSL is used because of client policy.
1128         *
1129         * b. if SSL was not used, then the target must not require it either.
1130         * The target may or may not support SSL (it is irrelevant).
1131         */

1132        if(_logger.isLoggable(Level.FINE)) {
1133        _logger.log(Level.FINE,
1134            "SecurityMechanismSelector.evaluate_client_conformance_ssl:"
1135            + " " + isSet(ssl_target_requires, Integrity.value)
1136            + " " + isSet(ssl_target_requires, Confidentiality.value)
1137            + " " + isSet(ssl_target_requires, EstablishTrustInClient.value)
1138            + " " + ssl_required
1139            + " " + ssl_supported
1140            + " " + ssl_used);
1141    }
1142
1143        if (ssl_used) {
1144            if (! (ssl_required || ssl_supported))
1145                return false; // security mechanism did not match
1146
} else {
1147            if (ssl_required)
1148                return false; // security mechanism did not match
1149
}
1150
1151        /* Check for conformance for SSL client authentication.
1152         *
1153         * a. if client performed SSL client authentication, then the target
1154         * must either require or support SSL client authentication. If
1155         * the target only supports, SSL client authentication is used
1156         * because of client security policy.
1157         *
1158         * b. if SSL client authentication was not used, then the target must
1159         * not require SSL client authentcation either. The target may or may
1160         * not support SSL client authentication (it is irrelevant).
1161         */

1162
1163        if(_logger.isLoggable(Level.FINE)) {
1164        _logger.log(Level.FINE,
1165            "SecurityMechanismSelector.evaluate_client_conformance_ssl:"
1166            + " " + certchain
1167            + " " + isSet(ssl_target_requires, EstablishTrustInClient.value)
1168            + " " + isSet(ssl_target_supports, EstablishTrustInClient.value));
1169    }
1170
1171        if (certchain != null) {
1172            if ( ! ( isSet(ssl_target_requires, EstablishTrustInClient.value)
1173                     || isSet(ssl_target_supports, EstablishTrustInClient.value)))
1174            return false; // security mechanism did not match
1175
} else {
1176            if (isSet(ssl_target_requires, EstablishTrustInClient.value))
1177                return false; // security mechanism did not match
1178
}
1179
1180        if(_logger.isLoggable(Level.FINE)) {
1181        _logger.log(Level.FINE,
1182            "SecurityMechanismSelector.evaluate_client_conformance_ssl: true");
1183    }
1184
1185        return true ; // mechanism matched
1186
} finally {
1187      if(_logger.isLoggable(Level.FINE)) {
1188          _logger.log(Level.FINE,
1189              "SecurityMechanismSelector.evaluate_client_conformance_ssl<-:");
1190      }
1191      }
1192    }
1193
1194   
1195   /* Evaluates a client's conformance to a security policies
1196    * at the client authentication layer.
1197    *
1198    * returns true if conformant ; else returns false
1199    */

1200    private boolean evaluate_client_conformance_ascontext(
1201                        SecurityContext ctx,
1202                        EjbIORConfigurationDescriptor iordesc)
1203    {
1204
1205        boolean client_authenticated = false;
1206
1207        // get requirements and supports at the client authentication layer
1208
AS_ContextSec ascontext = null;
1209        try {
1210            ascontext = this.ctc.createASContextSec(iordesc);
1211        } catch (Exception JavaDoc e) {
1212            _logger.log(Level.SEVERE, "iiop.createcontextsec_exception",e);
1213
1214            return false;
1215        }
1216   
1217        // ascontext should never be null - perhaps an exception should be raised.
1218
// for now return false;
1219
if (ascontext == null)
1220            return false;
1221            
1222        /*************************************************************************
1223         * Conformance Matrix:
1224         *
1225         * |------------|---------------------|---------------------|------------|
1226         * | ClientAuth | targetrequires.ETIC | targetSupports.ETIC | Conformant |
1227         * |------------|---------------------|---------------------|------------|
1228         * | Yes | 0 | 1 | Yes |
1229         * | Yes | 0 | 0 | No |
1230         * | Yes | 1 | X | Yes |
1231         * | No | 0 | X | Yes |
1232         * | No | 1 | X | No |
1233         * |------------|---------------------|---------------------|------------|
1234         *
1235         * Abbreviations: ETIC - EstablishTrusInClient
1236         *
1237         *************************************************************************/

1238
1239        if ( (ctx != null) && (ctx.authcls != null) && (ctx.subject != null))
1240            client_authenticated = true;
1241        else
1242            client_authenticated = false;
1243
1244        if (client_authenticated) {
1245            if ( ! ( isSet(ascontext.target_requires, EstablishTrustInClient.value)
1246                     || isSet(ascontext.target_supports, EstablishTrustInClient.value))){
1247            return false; // non conforming client
1248
}
1249            // match the target_name from client with the target_name in policy
1250

1251            byte [] client_tgtname = getTargetName(ctx.subject);
1252
1253            if (ascontext.target_name.length != client_tgtname.length){
1254                return false; // mechanism did not match.
1255
}
1256            for (int i=0; i < ascontext.target_name.length ; i ++)
1257                if (ascontext.target_name[i] != client_tgtname[i]){
1258                    return false; // mechanism did not match
1259
}
1260        } else {
1261            if ( isSet(ascontext.target_requires, EstablishTrustInClient.value)){
1262                return false; // no mechanism match.
1263
}
1264        }
1265        return true;
1266    }
1267
1268   /* Evaluates a client's conformance to a security policy
1269    * at the sas context layer. The security policy
1270    * is derived from the EjbIORConfigurationDescriptor.
1271    *
1272    * returns true if conformant ; else returns false
1273    */

1274    private boolean evaluate_client_conformance_sascontext(
1275                        SecurityContext ctx,
1276                        EjbIORConfigurationDescriptor iordesc)
1277    {
1278
1279        boolean caller_propagated = false;
1280
1281        // get requirements and supports at the sas context layer
1282
SAS_ContextSec sascontext = null;
1283        try {
1284            sascontext = this.ctc.createSASContextSec(iordesc);
1285        } catch (Exception JavaDoc e) {
1286            _logger.log(Level.SEVERE,"iiop.createcontextsec_exception",e);
1287            return false;
1288        }
1289   
1290        if (sascontext == null) // this should never be null
1291
return false;
1292            
1293        if ( (ctx != null) && (ctx.identcls != null) && (ctx.subject != null))
1294            caller_propagated = true;
1295        else
1296            caller_propagated = false;
1297
1298        if (caller_propagated) {
1299            if ( ! isSet(sascontext.target_supports, IdentityAssertion.value))
1300                return false; // target does not support IdentityAssertion
1301

1302            /* There is no need further checking here since SecServerRequestInterceptor
1303             * code filters out the following:
1304             * a. IdentityAssertions of types other than those required by level 0
1305             * (for e.g. IdentityExtension)
1306             * b. unsupported identity types.
1307             *
1308             * The checks are done in SecServerRequestInterceptor rather than here
1309             * to minimize code changes.
1310             */

1311            return true;
1312        }
1313        return true; // either caller was not propagated or mechanism matched.
1314
}
1315       
1316                                                    
1317
1318    /**
1319     * Evaluates a client's conformance to the security policies configured
1320     * on the target.
1321     * Returns true if conformant to the security policies
1322     * otherwise return false.
1323     *
1324     * Conformance checking is done as follows:
1325     * First, the object_id is mapped to the set of EjbIORConfigurationDescriptor.
1326     * Each EjbIORConfigurationDescriptor corresponds to a single CompoundSecMechanism
1327     * of the CSIv2 spec. A client is considered to be conformant if a
1328CompoundSecMechanism
1329     * consistent with the client's actions is found i.e. transport_mech,
1330as_context_mech
1331     * and sas_context_mech must all be consistent.
1332     *
1333     */

1334    private boolean evaluate_client_conformance(SecurityContext ctx,
1335                                                byte[] object_id,
1336                                                boolean ssl_used,
1337                                                X509Certificate JavaDoc[] certchain)
1338    {
1339        // Obtain the IOR configuration descriptors for the Ejb using
1340
// the object_id within the SecurityContext field.
1341

1342        // if object_id is null then nothing to evaluate. This is a sanity
1343
// check - for the object_id should never be null.
1344

1345        if (object_id == null)
1346            return true;
1347
1348        if (protocolMgr == null)
1349            protocolMgr = (POAProtocolMgr)Switch.getSwitch().getProtocolManager();
1350
1351        // Check to make sure protocolMgr is not null.
1352
// This could happen during server initialization or if this call
1353
// is on a callback object in the client VM.
1354
if (protocolMgr == null)
1355            return true;
1356
1357        EjbDescriptor ejbDesc = protocolMgr.getEjbDescriptor(object_id);
1358
1359        Set JavaDoc iorDescSet = null;
1360        if (ejbDesc != null) {
1361        iorDescSet = ejbDesc.getIORConfigurationDescriptors();
1362    }
1363    else {
1364        // Probably a non-EJB CORBA object.
1365
// Create a temporary EjbIORConfigurationDescriptor.
1366
iorDescSet = corbaIORDescSet;
1367    }
1368
1369    if(_logger.isLoggable(Level.FINE)) {
1370        _logger.log(Level.FINE,
1371            "SecurityMechanismSelector.evaluate_client_conformance: iorDescSet: " + iorDescSet);
1372    }
1373
1374        /* if there are no IORConfigurationDescriptors configured, then
1375         * no security policy is configured. So consider the client
1376         * to be conformant.
1377         */

1378        if (iorDescSet.isEmpty())
1379            return true;
1380
1381        // go through each EjbIORConfigurationDescriptor trying to find
1382
// a find a CompoundSecMechanism that matches client's actions.
1383
boolean checkSkipped = false;
1384        for (Iterator JavaDoc itr = iorDescSet.iterator(); itr.hasNext();) {
1385            EjbIORConfigurationDescriptor iorDesc =
1386                (EjbIORConfigurationDescriptor) itr.next();
1387            if(skip_client_conformance(iorDesc)){
1388        if(_logger.isLoggable(Level.FINE)) {
1389            _logger.log(Level.FINE,
1390                "SecurityMechanismSelector.evaluate_client_conformance: skip_client_conformance");
1391        }
1392                checkSkipped = true;
1393                continue;
1394            }
1395            if (! evaluate_client_conformance_ssl(iorDesc, ssl_used, certchain)){
1396        if(_logger.isLoggable(Level.FINE)) {
1397            _logger.log(Level.FINE,
1398                "SecurityMechanismSelector.evaluate_client_conformance: evaluate_client_conformance_ssl");
1399        }
1400                checkSkipped = false;
1401                continue;
1402            }
1403            if ( ! evaluate_client_conformance_ascontext(ctx, iorDesc)){
1404        if(_logger.isLoggable(Level.FINE)) {
1405            _logger.log(Level.FINE,
1406                "SecurityMechanismSelector.evaluate_client_conformance: evaluate_client_conformance_ascontext");
1407        }
1408                checkSkipped = false;
1409                continue;
1410            }
1411            if ( ! evaluate_client_conformance_sascontext(ctx, iorDesc)){
1412        if(_logger.isLoggable(Level.FINE)) {
1413            _logger.log(Level.FINE,
1414                "SecurityMechanismSelector.evaluate_client_conformance: evaluate_client_conformance_sascontext");
1415        }
1416               checkSkipped = false;
1417               continue;
1418            }
1419            return true; // security policy matched.
1420
}
1421        if(checkSkipped)
1422            return true;
1423        return false; // No matching security policy found
1424
}
1425        
1426     /** if ejb requires no security - then skip checking the client-conformance
1427     */

1428    private boolean skip_client_conformance (EjbIORConfigurationDescriptor ior){
1429        String JavaDoc none = ior.NONE;
1430    // sanity check
1431
if(ior == null){
1432       return false;
1433    }
1434        // SSL is required and/or supported either
1435
if(!none.equalsIgnoreCase(ior.getIntegrity())){
1436            return false;
1437        }
1438        if(!none.equalsIgnoreCase(ior.getConfidentiality())){
1439            return false;
1440        }
1441        if(!none.equalsIgnoreCase(ior.getEstablishTrustInClient())){
1442            return false;
1443        }
1444        // Username password is required
1445
if(ior.isAuthMethodRequired()){
1446            return false;
1447        }
1448        // caller propagation is supported
1449
if(!none.equalsIgnoreCase(ior.getCallerPropagation())){
1450            return false;
1451        }
1452        return true;
1453    }
1454    /**
1455     * Called by the target to interpret client credentials after validation.
1456     */

1457    public SecurityContext evaluateTrust(SecurityContext ctx, byte[] object_id)
1458        throws SecurityMechanismException
1459    {
1460        SecurityContext ssc = null;
1461        Socket JavaDoc socket = null;
1462
1463        // ssl_used is true if SSL was used.
1464
boolean ssl_used = false ;
1465
1466        // X509 Certificicate chain is non null if client has authenticated at
1467
// the SSL level.
1468

1469        X509Certificate JavaDoc[] certChain = null ;
1470
1471        // First gather all the information and then check the
1472
// conformance of the client to the security policies.
1473
// If the test for client conformance passes, then set the
1474
// security context.
1475

1476        ServerConnectionContext scc = getServerConnectionContext();
1477
1478        if(scc != null) {
1479            socket = scc.getSocket();
1480            if ((socket != null) && (socket instanceof SSLSocket)) {
1481                ssl_used = true; // SSL was used
1482
// checkif there is a transport principal
1483
SSLSocket sslSock = (SSLSocket) socket;
1484                SSLSession sslSession = sslSock.getSession();
1485                try {
1486                    certChain = (X509Certificate JavaDoc[])sslSession.getPeerCertificates();
1487                } catch(Exception JavaDoc e) {
1488                    if (_logger.isLoggable(Level.FINE)) {
1489                        _logger.log(Level.FINE, "iiop.cannot_get_peercert", e);
1490                    }
1491                }
1492            }
1493        }
1494
1495        // For a local invocation - we don't need to check the security
1496
// policies. The following condition guarantees the call is local
1497
// and thus bypassing policy checks.
1498
if (socket == null && ctx == null)
1499            return null;
1500
1501        if ( evaluate_client_conformance(ctx, object_id, ssl_used, certChain)
1502                                                                     == false) {
1503            String JavaDoc msg = "Trust evaluation failed because ";
1504            msg = msg + "client does not conform to configured security policies";
1505            throw new SecurityMechanismException(msg);
1506        }
1507 
1508        if ( ctx == null ) {
1509            if ( socket == null || !ssl_used || certChain == null ) {
1510                // Transport info is null and security context is null.
1511
// No need to set the anonymous credential here,
1512
// it will get set if any security operations
1513
// (e.g. getCallerPrincipal) are done.
1514
// Note: if the target object is not an EJB,
1515
// no security ctx is needed.
1516
return null;
1517            } else {
1518                // Set the transport principal in subject and
1519
// return the X500Name class
1520
ssc = new SecurityContext();
1521                X500Name x500Name = (X500Name) certChain[0].getSubjectDN();
1522                ssc.subject = new Subject JavaDoc();
1523                ssc.subject.getPublicCredentials().add(x500Name);
1524                ssc.identcls = X500Name.class;
1525                ssc.authcls = null;
1526                return ssc;
1527            }
1528        } else {
1529            ssc = ctx;
1530        }
1531
1532        Class JavaDoc authCls = ctx.authcls;
1533        Class JavaDoc identCls = ctx.identcls;
1534        ssc.subject = ctx.subject;
1535
1536        ssc.authcls = null;
1537        ssc.identcls = null;
1538
1539        if (identCls != null)
1540            ssc.identcls = identCls;
1541        else if (authCls != null)
1542            ssc.authcls = authCls;
1543        else
1544            ssc.identcls = AnonCredential.class;
1545
1546        return ssc;
1547    }
1548
1549    private boolean isSet(int val1, int val2) {
1550        if((val1 & val2) == val2) {
1551            return true;
1552        }
1553        return false;
1554    }
1555}
1556
1557
1558/**
1559 * This class that implements ConnectionExecutionContext that gets
1560 * stored in Thread Local Storage. If the current thread creates
1561 * child threads, the context info that is stored in the current
1562 * thread is automatically propogated to the child threads.
1563 *
1564 * Two class methods serve as a convinient way to set/get the
1565 * Context information within the current thread.
1566 *
1567 * Thread Local Storage is a concept introduced in JDK1.2. So, it
1568 * will not work on earlier releases of JDK.
1569 *
1570 * @see java.lang.ThreadLocal
1571 * @see java.lang.InheritableThreadLocal
1572 *
1573 */

1574class ConnectionExecutionContext {
1575    private static InheritableThreadLocal JavaDoc connCurrent= new InheritableThreadLocal JavaDoc();
1576
1577    /**
1578     * This method can be used to add a new hashtable for storing the
1579     * Thread specific context information. This method is useful to add a
1580     * deserialized Context information that arrived over the wire.
1581     * @param A hashtable that stores the current thread's context
1582     * information.
1583     */

1584    public static void setContext(Hashtable JavaDoc ctxTable) {
1585        if (ctxTable != null) {
1586            connCurrent.set(ctxTable);
1587        } else {
1588            connCurrent.set(new Hashtable JavaDoc());
1589        }
1590    }
1591
1592    /**
1593     * This method returns the hashtable that stores the thread specific
1594     * Context information.
1595     * @return The Context object stored in the current TLS. It always
1596     * returns a non null value;
1597     */

1598    public static Hashtable JavaDoc getContext() {
1599         if (connCurrent.get() == null) {
1600             setContext(null); // Create a new one...
1601
}
1602         return (Hashtable JavaDoc) connCurrent.get();
1603    }
1604    
1605    public InheritableThreadLocal JavaDoc getConnCurrent() {
1606        return connCurrent;
1607    }
1608    
1609    public void setConnCurrent(InheritableThreadLocal JavaDoc val) {
1610        this.connCurrent = val;
1611    }
1612    
1613}
1614
1615
Popular Tags