FileDocCategorySizeDatePackage
SecurityMechanismSelector.javaAPI DocGlassfish v2 API60727Mon Jul 16 17:00:06 BST 2007com.sun.enterprise.iiop.security

SecurityMechanismSelector

public final class SecurityMechanismSelector extends Object
This class is responsible for making various decisions for selecting security information to be sent in the IIOP message based on target configuration and client policies. Note: This class can be called concurrently by multiple client threads. However, none of its methods need to be synchronized because the methods either do not modify state or are idempotent.
author
Vivek Nagar
author
Harpreet Singh
author
Shing Wai Chan

Fields Summary
private static final Logger
_logger
public static final String
CLIENT_CONNECTION_CONTEXT
public static final String
SERVER_CONNECTION_CONTEXT
private static Set
corbaIORDescSet
private static boolean
sslRequired
private static final com.sun.enterprise.util.LocalStringManagerImpl
localStrings
private static com.sun.enterprise.iiop.POAProtocolMgr
protocolMgr
private CompoundSecMech
mechanism
Read the client and server preferences from the config files.
private org.omg.CORBA.ORB
orb
private com.sun.enterprise.iiop.CSIV2TaggedComponentInfo
ctc
Constructors Summary
public SecurityMechanismSelector()
Default constructor.


           
      
        this.orb = ORBManager.getORB();
        this.ctc = new CSIV2TaggedComponentInfo(orb);

    
Methods Summary
public SecurityContextevaluateTrust(SecurityContext ctx, byte[] object_id)
Called by the target to interpret client credentials after validation.

        SecurityContext ssc = null;
        Socket socket = null;

        // ssl_used is true if SSL was used.        
        boolean ssl_used        = false ;

        // X509 Certificicate chain is non null if client has authenticated at
        // the SSL level.

        X509Certificate[] certChain = null ;

        // First gather all the information and then check the 
        // conformance of the client to the security policies.
        // If the test for client conformance passes, then set the
        // security context.

        ServerConnectionContext scc = getServerConnectionContext();

        if(scc != null) {
            socket = scc.getSocket();
            if ((socket != null) && (socket instanceof SSLSocket)) {
                ssl_used = true; // SSL was used
                // checkif there is a transport principal
                SSLSocket sslSock = (SSLSocket) socket;
                SSLSession sslSession = sslSock.getSession();
                try {
                    certChain = (X509Certificate[])sslSession.getPeerCertificates();
                } catch(Exception e) {
                    if (_logger.isLoggable(Level.FINE)) {
                        _logger.log(Level.FINE, "iiop.cannot_get_peercert", e);
                    }
                }
            }
        }

        // For a local invocation - we don't need to check the security
        // policies. The following condition guarantees the call is local
        // and thus bypassing policy checks.
        if (socket == null && ctx == null)
            return null;

        if ( evaluate_client_conformance(ctx, object_id, ssl_used, certChain) 
                                                                     == false) {
            String msg = "Trust evaluation failed because ";
            msg = msg + "client does not conform to configured security policies";
            throw new SecurityMechanismException(msg);
        }            
 
        if ( ctx == null ) {
            if ( socket == null || !ssl_used || certChain == null )  {
                // Transport info is null and security context is null.
                // No need to set the anonymous credential here,
                // it will get set if any security operations 
                // (e.g. getCallerPrincipal) are done.
                // Note: if the target object is not an EJB, 
                // no security ctx is needed.
                return null;
            }  else {
                // Set the transport principal in subject and
                // return the X500Name class
                ssc = new SecurityContext();
                X500Name x500Name = (X500Name) certChain[0].getSubjectDN();
                ssc.subject = new Subject();
                ssc.subject.getPublicCredentials().add(x500Name);
                ssc.identcls = X500Name.class;
                ssc.authcls = null;
                return ssc;
            }
        } else {
            ssc = ctx;
        }

        Class authCls = ctx.authcls;
        Class identCls = ctx.identcls;
        ssc.subject = ctx.subject;

        ssc.authcls = null;
        ssc.identcls = null;

        if (identCls != null)
            ssc.identcls = identCls;
        else if (authCls != null)
            ssc.authcls = authCls;
        else
            ssc.identcls = AnonCredential.class;

        return ssc;
    
private booleanevaluate_client_conformance(SecurityContext ctx, byte[] object_id, boolean ssl_used, java.security.cert.X509Certificate[] certchain)
Evaluates a client's conformance to the security policies configured on the target. Returns true if conformant to the security policies otherwise return false. Conformance checking is done as follows: First, the object_id is mapped to the set of EjbIORConfigurationDescriptor. Each EjbIORConfigurationDescriptor corresponds to a single CompoundSecMechanism of the CSIv2 spec. A client is considered to be conformant if a CompoundSecMechanism consistent with the client's actions is found i.e. transport_mech, as_context_mech and sas_context_mech must all be consistent.

        // Obtain the IOR configuration descriptors for the Ejb using
        // the object_id within the SecurityContext field.

        // if object_id is null then nothing to evaluate. This is a sanity
        // check - for the object_id should never be null.
        
        if (object_id == null)
            return true;

        if (protocolMgr == null)
            protocolMgr = (POAProtocolMgr)Switch.getSwitch().getProtocolManager();

        // Check to make sure protocolMgr is not null. 
        // This could happen during server initialization or if this call
        // is on a callback object in the client VM. 
        if (protocolMgr == null)
            return true;

        EjbDescriptor ejbDesc = protocolMgr.getEjbDescriptor(object_id);

        Set iorDescSet = null;
        if (ejbDesc != null) {
	    iorDescSet = ejbDesc.getIORConfigurationDescriptors();
	}
	else {
	    // Probably a non-EJB CORBA object.
	    // Create a temporary EjbIORConfigurationDescriptor.
	    iorDescSet = corbaIORDescSet;
	}

	if(_logger.isLoggable(Level.FINE)) {
	    _logger.log(Level.FINE,
			"SecurityMechanismSelector.evaluate_client_conformance: iorDescSet: " + iorDescSet);
	}

        /* if there are no IORConfigurationDescriptors configured, then
         * no security policy is configured. So consider the client 
         * to be conformant.
         */
        if (iorDescSet.isEmpty())
            return true;

        // go through each EjbIORConfigurationDescriptor trying to find
        // a find a CompoundSecMechanism that matches client's actions.
        boolean checkSkipped = false;
        for (Iterator itr = iorDescSet.iterator(); itr.hasNext();) {
            EjbIORConfigurationDescriptor iorDesc = 
                (EjbIORConfigurationDescriptor) itr.next();
            if(skip_client_conformance(iorDesc)){
		if(_logger.isLoggable(Level.FINE)) {
		    _logger.log(Level.FINE,
				"SecurityMechanismSelector.evaluate_client_conformance: skip_client_conformance");
		}
                checkSkipped = true;
                continue;
            }
            if (! evaluate_client_conformance_ssl(iorDesc, ssl_used, certchain)){
		if(_logger.isLoggable(Level.FINE)) {
		    _logger.log(Level.FINE,
				"SecurityMechanismSelector.evaluate_client_conformance: evaluate_client_conformance_ssl");
		}
                checkSkipped = false;
                continue;
            }
            if ( ! evaluate_client_conformance_ascontext(ctx, iorDesc)){
		if(_logger.isLoggable(Level.FINE)) {
		    _logger.log(Level.FINE,
				"SecurityMechanismSelector.evaluate_client_conformance: evaluate_client_conformance_ascontext");
		}
                checkSkipped = false;
                continue;
            }
            if  ( ! evaluate_client_conformance_sascontext(ctx, iorDesc)){
		if(_logger.isLoggable(Level.FINE)) {
		    _logger.log(Level.FINE,
				"SecurityMechanismSelector.evaluate_client_conformance: evaluate_client_conformance_sascontext");
		}
               checkSkipped = false;
               continue;
            }
            return true;  // security policy matched.
        }
        if(checkSkipped)
            return true;
        return false; // No matching security policy found
    
private booleanevaluate_client_conformance_ascontext(SecurityContext ctx, com.sun.enterprise.deployment.EjbIORConfigurationDescriptor iordesc)


        boolean client_authenticated = false;

        // get requirements and supports at the client authentication layer
        AS_ContextSec ascontext = null;
        try {
            ascontext = this.ctc.createASContextSec(iordesc);
        } catch (Exception e) {
            _logger.log(Level.SEVERE, "iiop.createcontextsec_exception",e);

            return false;
        }
   
        // ascontext should never be null - perhaps an exception should be raised.
        // for now return false;
        if (ascontext == null)
            return false;
            
        /*************************************************************************
         * Conformance Matrix:
         *
         * |------------|---------------------|---------------------|------------|
         * | ClientAuth | targetrequires.ETIC | targetSupports.ETIC | Conformant |
         * |------------|---------------------|---------------------|------------|
         * |     Yes    |          0          |      1              |    Yes     |
         * |     Yes    |          0          |      0              |    No      |
         * |     Yes    |          1          |      X              |    Yes     |
         * |     No     |          0          |      X              |    Yes     |
         * |     No     |          1          |      X              |    No      |
         * |------------|---------------------|---------------------|------------|
         *
         * Abbreviations: ETIC - EstablishTrusInClient
         * 
         *************************************************************************/

        if  ( (ctx != null) && (ctx.authcls != null) &&  (ctx.subject != null))
            client_authenticated = true;
        else
            client_authenticated = false;

        if (client_authenticated) {
            if ( ! ( isSet(ascontext.target_requires, EstablishTrustInClient.value)
                     || isSet(ascontext.target_supports, EstablishTrustInClient.value))){
            return false; // non conforming client
            }
            // match the target_name from client with the target_name in policy 

            byte [] client_tgtname = getTargetName(ctx.subject);

            if (ascontext.target_name.length != client_tgtname.length){
                return false; // mechanism did not match.
            }            
            for (int i=0; i < ascontext.target_name.length ; i ++)
                if (ascontext.target_name[i] != client_tgtname[i]){
                    return false; // mechanism did not match
                }
        } else { 
            if ( isSet(ascontext.target_requires, EstablishTrustInClient.value)){
                return false;  // no mechanism match.
            }
        }
        return true;
    
private booleanevaluate_client_conformance_sascontext(SecurityContext ctx, com.sun.enterprise.deployment.EjbIORConfigurationDescriptor iordesc)


        boolean caller_propagated = false;

        // get requirements and supports at the sas context layer
        SAS_ContextSec sascontext = null;
        try {
            sascontext = this.ctc.createSASContextSec(iordesc);
        } catch (Exception e) {
            _logger.log(Level.SEVERE,"iiop.createcontextsec_exception",e);
            return false;
        }
   
        if (sascontext == null)  // this should never be null
            return false;
            
        if  ( (ctx != null) && (ctx.identcls != null) &&  (ctx.subject != null))
            caller_propagated = true;
        else
            caller_propagated = false;

        if (caller_propagated) {
            if ( ! isSet(sascontext.target_supports, IdentityAssertion.value))
                return false; // target does not support IdentityAssertion

            /* There is no need further checking here since SecServerRequestInterceptor
             * code filters out the following:
             * a. IdentityAssertions of types other than those required by level 0 
             *    (for e.g. IdentityExtension)
             * b. unsupported identity types.
             * 
             * The checks are done in SecServerRequestInterceptor rather than here
             * to minimize code changes.
             */
            return true;
        }
        return true; //  either caller was not propagated or mechanism matched.
    
private booleanevaluate_client_conformance_ssl(com.sun.enterprise.deployment.EjbIORConfigurationDescriptor iordesc, boolean ssl_used, java.security.cert.X509Certificate[] certchain)

      try {
        if(_logger.isLoggable(Level.FINE)) {
	    _logger.log(Level.FINE,
			"SecurityMechanismSelector.evaluate_client_conformance_ssl->:");
	}
	
        boolean ssl_required  = false;
        boolean ssl_supported = false;
        int ssl_target_requires = 0;
        int ssl_target_supports = 0;

        /*************************************************************************
         * Conformance Matrix:
         *
         * |---------------|---------------------|---------------------|------------|
         * | SSLClientAuth | targetrequires.ETIC | targetSupports.ETIC | Conformant |
         * |---------------|---------------------|---------------------|------------|
         * |     Yes       |          0          |      1              |    Yes     |
         * |     Yes       |          0          |      0              |    No      |
         * |     Yes       |          1          |      X              |    Yes     |
         * |     No        |          0          |      X              |    Yes     |
         * |     No        |          1          |      X              |    No      |
         * |---------------|---------------------|---------------------|------------|
         *
         *************************************************************************/

        // gather the configured SSL security policies.
 
        ssl_target_requires = this.ctc.getTargetRequires(iordesc);
        ssl_target_supports = this.ctc.getTargetSupports(iordesc);

        if (    isSet(ssl_target_requires, Integrity.value)
             || isSet(ssl_target_requires, Confidentiality.value)
             || isSet(ssl_target_requires, EstablishTrustInClient.value))
            ssl_required = true;
        else
            ssl_required = false;

        if ( ssl_target_supports != 0)
            ssl_supported = true;
        else
            ssl_supported = false;

        /* Check for conformance for using SSL usage.
         * 
         * a. if SSL was used, then either the target must require or support
         *    SSL. In the latter case, SSL is used because of client policy.
         *
         * b. if SSL was not used, then the target must not require it either.
         *    The target may or may not support SSL (it is irrelevant).
         */
        if(_logger.isLoggable(Level.FINE)) {
	    _logger.log(Level.FINE,
			"SecurityMechanismSelector.evaluate_client_conformance_ssl:"
			+ " " + isSet(ssl_target_requires, Integrity.value)
			+ " " + isSet(ssl_target_requires, Confidentiality.value)
			+ " " + isSet(ssl_target_requires, EstablishTrustInClient.value)
			+ " " + ssl_required
			+ " " + ssl_supported
			+ " " + ssl_used);
	}

        if (ssl_used) {
            if (! (ssl_required || ssl_supported))
                return false;  // security mechanism did not match
        } else {
            if (ssl_required)
                return false;  // security mechanism did not match
        }

        /* Check for conformance for SSL client authentication.
         *
         * a. if client performed SSL client authentication, then the target
         *    must either require or support SSL client authentication. If 
         *    the target only supports, SSL client authentication is used
         *    because of client security policy.
         *
         * b. if SSL client authentication was not used, then the target must
         *    not require SSL client authentcation either. The target may or may 
         *    not support SSL client authentication (it is irrelevant).
         */

        if(_logger.isLoggable(Level.FINE)) {
	    _logger.log(Level.FINE,
			"SecurityMechanismSelector.evaluate_client_conformance_ssl:"
			+ " " + certchain
			+ " " + isSet(ssl_target_requires, EstablishTrustInClient.value)
			+ " " + isSet(ssl_target_supports, EstablishTrustInClient.value));
	}

        if (certchain != null) {
            if ( ! ( isSet(ssl_target_requires, EstablishTrustInClient.value)
                     || isSet(ssl_target_supports, EstablishTrustInClient.value)))
            return false; // security mechanism did not match
        } else {
            if (isSet(ssl_target_requires, EstablishTrustInClient.value))
                return false; // security mechanism did not match
        }

        if(_logger.isLoggable(Level.FINE)) {
	    _logger.log(Level.FINE,
			"SecurityMechanismSelector.evaluate_client_conformance_ssl: true");
	}

        return true ; // mechanism matched
      } finally {
	  if(_logger.isLoggable(Level.FINE)) {
	      _logger.log(Level.FINE,
			  "SecurityMechanismSelector.evaluate_client_conformance_ssl<-:");
	  }
      }
    
public ConnectionContextgetClientConnectionContext()

        Hashtable h = ConnectionExecutionContext.getContext();
        ConnectionContext scc = 
            (ConnectionContext) h.get(CLIENT_CONNECTION_CONTEXT);
        return scc;
    
public com.sun.enterprise.iiop.CSIV2TaggedComponentInfogetCtc()

        return ctc;
    
private SecurityContextgetIdentity()
Get the principal/distinguished name from thread local storage.

return
the security context.

        if (_logger.isLoggable(Level.FINE)) {
            _logger.log(Level.FINE, "Getting PRINCIPAL/DN from TLS");
        }

        SecurityContext ctx = new SecurityContext();
        final SecurityContext sCtx = ctx;
	// get stuff from the SecurityContext class
        com.sun.enterprise.security.SecurityContext scontext = 
            com.sun.enterprise.security.SecurityContext.getCurrent();
        if ((scontext == null) ||
             scontext.didServerGenerateCredentials()){  
            
            // a default guest/guest123 was created
            sCtx.identcls = AnonCredential.class;
            
            AccessController.doPrivileged(new PrivilegedAction() {
                public java.lang.Object run(){
                    // remove all the public and private credentials 
                    Subject sub = new Subject();
                    sCtx.subject = sub; 
                    sCtx.subject.getPublicCredentials().add(new AnonCredential());
                    return null;
                }
            });
            return sCtx;
        }

        Subject s = getSubjectFromSecurityCurrent();
        ctx.subject = s;

        // Figure out the credential class
        final Subject sub = s;
        Set credSet = 
            (Set) AccessController.doPrivileged(new PrivilegedAction() {
                public java.lang.Object run() {
                    return sub.getPrivateCredentials(PasswordCredential.class);
                }
            });
        if(credSet.size() == 1) {
            ctx.identcls = GSSUPName.class;
            final Set cs = credSet;
            Subject subj = (Subject) AccessController.doPrivileged(new
            PrivilegedAction() { 
                public java.lang.Object run() {    
                    Subject ss = new Subject();
                    Iterator iter = cs.iterator();
                    PasswordCredential pc = (PasswordCredential) iter.next();
                    GSSUPName gssname = new GSSUPName(pc.getUser(), pc.getRealm());
                    ss.getPublicCredentials().add(gssname);
                    return ss;
                }
            });
            ctx.subject = subj;
            return ctx;
        }

        credSet = s.getPublicCredentials();
        if(credSet.size() != 1) {
            _logger.log(Level.SEVERE,"iiop.principal_error");
            return null;
        } else {
            Iterator credIter = credSet.iterator();
            if(credIter.hasNext()) {
                Object o = credIter.next();
                if(o instanceof GSSUPName) {
                    ctx.identcls = GSSUPName.class;
                } else if(o instanceof X500Name) {
                    ctx.identcls = X500Name.class;
                } else {
                    ctx.identcls = X509CertificateCredential.class;
                }
            } else {
        	_logger.log(Level.SEVERE,"iiop.credential_error");
                return null;
            }
        }
        return ctx;
    
public CompoundSecMechgetMechanism()

        return mechanism;
    
public org.omg.CORBA.ORBgetOrb()

        return orb;
    
public com.sun.corba.ee.spi.transport.SocketInfogetSSLPort(com.sun.corba.ee.spi.ior.IOR ior, ConnectionContext ctx)
This method determines if SSL should be used to connect to the target based on client and target policies. It will return null if SSL should not be used or an SocketInfo containing the SSL port if SSL should be used.

        SocketInfo info = null;
        try {
            mechanism = selectSecurityMechanism(ior);
        } catch(SecurityMechanismException sme) {
            throw new RuntimeException(sme.getMessage());
        }
        ctx.setIOR(ior);
        ctx.setMechanism(mechanism);

        TLS_SEC_TRANS ssl = null;
        if ( mechanism != null ) {
            ssl = ctc.getSSLInformation(mechanism);
        }

        if (ssl == null) {
            if (sslRequired) {
                // Attempt to create SSL connection to host, ORBInitialPort
                IIOPProfileTemplate templ = (IIOPProfileTemplate)
                    ior.getProfile().getTaggedProfileTemplate();
                IIOPAddress addr = templ.getPrimaryAddress();
                info = IORToSocketInfoImpl.createSocketInfo(
		        "SecurityMechanismSelector1",
                        "SSL", addr.getHost(), ORBManager.getORBInitialPort());
                return info;
            } else {
                return null;
            }
        }

        int targetRequires = ssl.target_requires;
        int targetSupports = ssl.target_supports;
        
        /*
         * If target requires any of Integrity, Confidentiality or 
         * EstablishTrustInClient, then SSL is used.
         */
        if (isSet(targetRequires, Integrity.value) || 
                isSet(targetRequires, Confidentiality.value) ||
                isSet(targetRequires, EstablishTrustInClient.value)) {
            if (_logger.isLoggable(Level.FINE)) {
                 _logger.log(Level.FINE, "Target requires SSL");
            }
            ctx.setSSLUsed(true);
            String type = "SSL";
            if(isSet(targetRequires, EstablishTrustInClient.value)) {
                type = "SSL_MUTUALAUTH";
                ctx.setSSLClientAuthenticationOccurred(true);
            } 
            short sslport = ssl.addresses[0].port;
            int ssl_port = Utility.shortToInt(sslport);
            String host_name = ssl.addresses[0].host_name;
            
            info = IORToSocketInfoImpl.createSocketInfo(
		    "SecurityMechanismSelector2",
                    type, host_name, ssl_port);

            return info;
        } else if (isSet(targetSupports, Integrity.value) || 
                    isSet(targetSupports, Confidentiality.value) ||
                    isSet(targetSupports, EstablishTrustInClient.value)) {
            if (_logger.isLoggable(Level.FINE)) {
                _logger.log(Level.FINE, "Target supports SSL");
            }

            if ( sslRequired ) {
                if (_logger.isLoggable(Level.FINE)) {
                    _logger.log(Level.FINE, "Client is configured to require SSL for the target");
                }

                ctx.setSSLUsed(true);
                short sslport = ssl.addresses[0].port;
                String host_name = ssl.addresses[0].host_name;
                int ssl_port = Utility.shortToInt(sslport);
                info = IORToSocketInfoImpl.createSocketInfo(
		        "SecurityMechanismSelector3",
                        "SSL", host_name, ssl_port);
                return info;
            } else {
                return null;
            }
        } else if ( sslRequired ) {
	    throw new RuntimeException("SSL required by client but not supported by server.");
	} else {
	    return null;
	}
    
public java.util.ListgetSSLPorts(com.sun.corba.ee.spi.ior.IOR ior, ConnectionContext ctx)

        try {
            mechanism = selectSecurityMechanism(ior);
        } catch(SecurityMechanismException sme) {
            throw new RuntimeException(sme.getMessage());
        }
        ctx.setIOR(ior);
        ctx.setMechanism(mechanism);

        TLS_SEC_TRANS ssl = null;
        if ( mechanism != null ) {
            ssl = ctc.getSSLInformation(mechanism);
        }

        if (ssl == null) {
            if (sslRequired) {
                // Attempt to create SSL connection to host, ORBInitialPort
                IIOPProfileTemplate templ = (IIOPProfileTemplate)
                    ior.getProfile().getTaggedProfileTemplate();
                IIOPAddress addr = templ.getPrimaryAddress();
                SocketInfo info = IORToSocketInfoImpl.createSocketInfo(
		        "SecurityMechanismSelector1",
                        "SSL", addr.getHost(), ORBManager.getORBInitialPort());
                //SocketInfo[] sInfos = new SocketInfo[]{info};
                List<SocketInfo> sInfos = new ArrayList<SocketInfo>();
                sInfos.add(info);
                return sInfos;
            } else {
                return null;
            }
        }

        int targetRequires = ssl.target_requires;
        int targetSupports = ssl.target_supports;
        
        /*
         * If target requires any of Integrity, Confidentiality or 
         * EstablishTrustInClient, then SSL is used.
         */
        if (isSet(targetRequires, Integrity.value) || 
                isSet(targetRequires, Confidentiality.value) ||
                isSet(targetRequires, EstablishTrustInClient.value)) {
            if (_logger.isLoggable(Level.FINE)) {
                 _logger.log(Level.FINE, "Target requires SSL");
            }
            ctx.setSSLUsed(true);
            String type = "SSL";
            if(isSet(targetRequires, EstablishTrustInClient.value)) {
                type = "SSL_MUTUALAUTH";
                ctx.setSSLClientAuthenticationOccurred(true);
            } 
            //SocketInfo[] socketInfos = new SocketInfo[ssl.addresses.size];
            List<SocketInfo> socketInfos = new ArrayList<SocketInfo>();
            for(int addressIndex =0; addressIndex < ssl.addresses.length; addressIndex++){
                short sslport = ssl.addresses[addressIndex].port;
                int ssl_port = Utility.shortToInt(sslport);
                String host_name = ssl.addresses[addressIndex].host_name;
            
                SocketInfo sInfo = IORToSocketInfoImpl.createSocketInfo(
		    "SecurityMechanismSelector2",
                    type, host_name, ssl_port);
                socketInfos.add(sInfo);
            }
            return socketInfos;
        } else if (isSet(targetSupports, Integrity.value) || 
                    isSet(targetSupports, Confidentiality.value) ||
                    isSet(targetSupports, EstablishTrustInClient.value)) {
            if (_logger.isLoggable(Level.FINE)) {
                _logger.log(Level.FINE, "Target supports SSL");
            }

            if ( sslRequired ) {
                if (_logger.isLoggable(Level.FINE)) {
                    _logger.log(Level.FINE, "Client is configured to require SSL for the target");
                }

                ctx.setSSLUsed(true);
                //SocketInfo[] socketInfos = new SocketInfo[ssl.addresses.size];
                List<SocketInfo> socketInfos = new ArrayList<SocketInfo>();
                for(int addressIndex =0; addressIndex < ssl.addresses.length; addressIndex++){
                    short sslport = ssl.addresses[addressIndex].port;
                    int ssl_port = Utility.shortToInt(sslport);
                    String host_name = ssl.addresses[addressIndex].host_name;

                    SocketInfo sInfo = IORToSocketInfoImpl.createSocketInfo(
                        "SecurityMechanismSelector3",
                        "SSL", host_name, ssl_port);
                    socketInfos.add(sInfo);
                }
                return socketInfos;                
            } else {
                return null;
            }
        } else if ( sslRequired ) {
	    throw new RuntimeException("SSL required by client but not supported by server.");
	} else {
	    return null;
	}
    
public SecurityContextgetSecurityContextForAppClient(com.sun.enterprise.ComponentInvocation ci, boolean sslUsed, boolean clientAuthOccurred)
Create the security context to be used by the CSIV2 layer to marshal in the service context of the IIOP message from an appclient or standalone client.

return
the security context.


        return sendUsernameAndPassword(ci, sslUsed, clientAuthOccurred);
    
public SecurityContextgetSecurityContextForWebOrEJB(com.sun.enterprise.ComponentInvocation ci, boolean sslUsed, boolean clientAuthOccurred)
Create the security context to be used by the CSIV2 layer to marshal in the service context of the IIOP message from an web component or EJB invoking another EJB.

return
the security context.


        SecurityContext ctx = null;
        if(!sslUsed) {
	    ctx = propagateIdentity(false, ci);
	} else {
	    ctx = propagateIdentity(clientAuthOccurred, ci);
	}
	return ctx;
    
public static ServerConnectionContextgetServerConnectionContext()

        Hashtable h = ConnectionExecutionContext.getContext();
        ServerConnectionContext scc = 
            (ServerConnectionContext) h.get(SERVER_CONNECTION_CONTEXT);
        return scc;
    
private javax.security.auth.SubjectgetSubjectFromSecurityCurrent()

        com.sun.enterprise.security.SecurityContext sc = null;
        sc = com.sun.enterprise.security.SecurityContext.getCurrent();
        if(sc == null) {
            if(_logger.isLoggable(Level.FINE)) {
        	_logger.log(Level.FINE," SETTING GUEST ---");
            }
            sc = com.sun.enterprise.security.SecurityContext.init();
        }
        if(sc == null) {
            throw new SecurityMechanismException("Could not find " +
                        " security information");
        }
        Subject s = sc.getSubject();
        if(s == null) {
            throw new SecurityMechanismException("Could not find " +
                " subject information in the security context.");
        }
        if (_logger.isLoggable(Level.FINE)) {
            _logger.log(Level.FINE, "Subject in security current:" + s);
        }
        return s;
    
private byte[]getTargetName(javax.security.auth.Subject subj)

  
        byte[] tgt_name = {} ;

        final Subject sub = subj;
        final Set credset = 
            (Set) AccessController.doPrivileged(new PrivilegedAction() {
                public java.lang.Object run() {
                    return sub.getPrivateCredentials(PasswordCredential.class);
                }
            });
        if(credset.size() == 1) {
            tgt_name = (byte[]) AccessController.doPrivileged(new PrivilegedAction() { 
                public java.lang.Object run() {    
                    Iterator iter = credset.iterator();
                    PasswordCredential pc = (PasswordCredential) iter.next();
                    return pc.getTargetName();
                }
            });
        }
        return tgt_name;
    
private SecurityContextgetUsernameAndPassword(com.sun.enterprise.ComponentInvocation ci)
Get the username and password either from the JAAS subject or from thread local storage. For appclients if login has'nt happened this method would trigger login and popup a user interface to gather authentication information.

return
the security context.

        try {
            Subject s = null;
            if(ci == null) {
		// Standalone client ... Changed the security context 
		// from which to fetch the subject
                com.sun.enterprise.security.ClientSecurityContext sc = 
                    com.sun.enterprise.security.ClientSecurityContext.getCurrent();
                if(sc == null) {
                    return null;
                }
                s = sc.getSubject();
                if (_logger.isLoggable(Level.FINE)) {
                    _logger.log(Level.FINE, "SUBJECT:" + s);
                }
            } else {
                Object obj = ci.getContainerContext();
                if(obj instanceof AppContainer) {
		    // get the subject
                    com.sun.enterprise.security.ClientSecurityContext sc = 
                        com.sun.enterprise.security.ClientSecurityContext.getCurrent();
                    if(sc == null) {
			s = LoginContextDriver.doClientLogin(
                                AppContainer.USERNAME_PASSWORD,
                                AppContainer.getCallbackHandler());
                    } else {
                        s = sc.getSubject();
                    }
                } else {
                    // web/ejb
                    s = getSubjectFromSecurityCurrent();
                    // TODO check if username/password is available
                    // if not throw exception
                }
            }
            SecurityContext ctx = new SecurityContext();
            final Subject sub = s;
            ctx.subject = s;
            // determining if run-as has been used
            Set privateCredSet = 
                (Set) AccessController.doPrivileged(new PrivilegedAction() {
                    public java.lang.Object run() {
                        return sub.getPrivateCredentials();
                    }
                });
            if (privateCredSet.isEmpty()) { // this is runas case dont set
                if (_logger.isLoggable(Level.FINE)) {
                    _logger.log(Level.FINE, "no private credential run as mode");
                }
                ctx.authcls = null; // the auth class
                ctx.identcls = GSSUPName.class;
                
            } else{
                /** lookup the realm name that is required by the server
                 * and set it up in the PasswordCredential class.
                 */
                AS_ContextSec asContext = mechanism.as_context_mech;
                final byte[] target_name = asContext.target_name;
                byte[] _realm = GSSUtils.importName(GSSUtils.GSSUP_MECH_OID, target_name);
                final String realm_name = new String(_realm);
                final Iterator it = privateCredSet.iterator();
                for(;it.hasNext();){
                    AccessController.doPrivileged(new PrivilegedAction(){
                        public java.lang.Object run(){
                            PasswordCredential pc = (PasswordCredential) it.next();
                            pc.setRealm(realm_name);
                            return null;
                        }
                    });
                }
                ctx.authcls = PasswordCredential.class;
            }
            return ctx;
        } catch(Exception e) {
            _logger.log(Level.SEVERE,"iiop.user_password_exception",e);
            return null;
        }
    
public booleanisIdentityTypeSupported(SAS_ContextSec sas)

        int ident_token = sas.supported_identity_types;
        // the identity token matches atleast one of the types we support
        int value = ident_token &
            CSIV2TaggedComponentInfo.SUPPORTED_IDENTITY_TOKEN_TYPES;
        if (value != 0)
            return true;
        else 
            return false;
    
private booleanisMechanismSupported(SAS_ContextSec sas)

        byte[][] mechanisms = sas.supported_naming_mechanisms;
        byte[] mechSupported = Utility.getMechanism();

	if (mechSupported == null) {
	    return false;
	}
        if (mechanisms[0].length != mechSupported.length)
            return false;
        for (int i=0; i<mechanisms[0].length; i++){
            if (mechanisms[0][i] != mechSupported[i])
                return false;
        }
        return true;    
    
private booleanisSet(int val1, int val2)

        if((val1 & val2) == val2) {
            return true;
        }
        return false;
    
private SecurityContextpropagateIdentity(boolean clientAuth, com.sun.enterprise.ComponentInvocation ci)
Get the security context to propagate principal/distinguished name in the service context.

param
clientAuth whether SSL client authentication has happened.
return
the security context.
exception
SecurityMechanismException if there was an error.

            
        SecurityContext ctx = null;
        if(mechanism == null) {
            return null;
        }
        AS_ContextSec asContext = mechanism.as_context_mech;
        SAS_ContextSec sasContext = mechanism.sas_context_mech;
        if (_logger.isLoggable(Level.FINE)) {
            _logger.log(Level.FINE, "SAS CONTEXT's target_requires=" + sasContext.target_requires);
            _logger.log(Level.FINE, "SAS CONTEXT's target_supports=" + sasContext.target_supports);
        }

        if(isSet(asContext.target_requires, EstablishTrustInClient.value)) {
            ctx = getUsernameAndPassword(ci);
            if (ctx.authcls == null){ // run as mode cannot send password
                String errmsg =
localStrings.getLocalString("securitymechansimselector.runas_cannot_propagate_username_password",
"Cannot propagate username/password required by target when using run as identity");

            _logger.log(Level.SEVERE,"iiop.runas_error",errmsg);
            throw new SecurityMechanismException (errmsg);
            }
        } else if(isSet(sasContext.target_supports, IdentityAssertion.value) ||
                  isSet(sasContext.target_requires, IdentityAssertion.value)) {
            // called from the client side. thus before getting the identity. check the
            // mechanisms and the identity token supported
            if(!isIdentityTypeSupported(sasContext)){
                String errmsg =
                    localStrings.getLocalString("securitymechanismselector.invalid_identity_type",
                                                "The given identity token is unsupported.");
                throw new InvalidIdentityTokenException(errmsg);
            }
            if (sasContext.target_supports == IdentityAssertion.value){
                if(!isMechanismSupported(sasContext)){
                    String errmsg =
                        localStrings.getLocalString("securitymechanismselector.invalid_mechanism",
                                                    "The given mechanism type is unsupported.");
                _logger.log(Level.SEVERE,"iiop.unsupported_type_error",errmsg);
                throw new InvalidMechanismException(errmsg);
                }
            }

            // propagate principal/certificate/distinguished name
            ctx = getIdentity();
        } else if(isSet(asContext.target_supports, 
                        EstablishTrustInClient.value)) {
            if (clientAuth) {   // client auth done we can send password
                ctx = getUsernameAndPassword(ci);
                if (ctx.authcls == null) {
                    return null; // runas mode dont have username/password
                                //  dont really need to send it too
                }
            } else { // not sending anything for unauthenticated client
                return null;
            }
        } else{
            return null;        //  will never come here
        }
        return ctx;
    
public SecurityContextselectSecurityContext(com.sun.corba.ee.spi.ior.IOR ior)
Select the security context to be used by the CSIV2 layer based on whether the current component is an application client or a web/EJB component.

        SecurityContext context = null;   

	ConnectionContext cc = new ConnectionContext();
        getSSLPort(ior, cc);
        setClientConnectionContext(cc); 


        mechanism = cc.getMechanism();
        if(mechanism == null) {
            return null;
        }
        boolean sslUsed = cc.getSSLUsed();
        boolean clientAuthOccurred = cc.getSSLClientAuthenticationOccurred();
        InvocationManager im = Switch.getSwitch().getInvocationManager();
        if(im == null) {
            // Standalone client
            context = getSecurityContextForAppClient(null, sslUsed,
clientAuthOccurred); 
            return context;
        }

        if (_logger.isLoggable(Level.FINE)) {
            _logger.log(Level.FINE, "SSL used:" + sslUsed + " SSL Mutual auth:" + clientAuthOccurred);
        }

        ComponentInvocation ci = null;
        // BEGIN IASRI# 4646060
        ci = im.getCurrentInvocation();
        if (ci == null) {
        // END IASRI# 4646060
            return null;
        }
        Object obj = ci.getContainerContext();
        if(obj instanceof AppContainer) {
            context = getSecurityContextForAppClient(ci, sslUsed, clientAuthOccurred);
        } else {
            context = getSecurityContextForWebOrEJB(ci, sslUsed, clientAuthOccurred);
        }
        return context;
    
public CompoundSecMechselectSecurityMechanism(com.sun.corba.ee.spi.ior.IOR ior)

        CompoundSecMech[] mechList = ctc.getSecurityMechanisms(ior);
        CompoundSecMech mech = selectSecurityMechanism(mechList);
        return mech;
    
private CompoundSecMechselectSecurityMechanism(CompoundSecMech[] mechList)
Select the security mechanism from the list of compound security mechanisms.

        // We should choose from list of compound security mechanisms
        // which are in decreasing preference order. Right now we select
        // the first one.
        if(mechList == null || mechList.length == 0) {
            return null;
        }
        CompoundSecMech mech = null;
        for(int i = 0; i < mechList.length; i++) {
            mech = mechList[i];
            boolean useMech = useMechanism(mech);
            if(useMech) {
                return mech;
            }
        }
        throw new SecurityMechanismException("Cannot use any of the " +
            " target's supported mechanisms");
    
private SecurityContextsendUsernameAndPassword(com.sun.enterprise.ComponentInvocation ci, boolean sslUsed, boolean clientAuthOccurred)
Get the security context to send username and password in the service context.

param
whether username/password will be sent over plain IIOP or over IIOP/SSL.
return
the security context.
exception
SecurityMechanismException if there was an error.

        SecurityContext ctx = null;
        if(mechanism == null) {
            return null;
        }
        AS_ContextSec asContext = mechanism.as_context_mech;
        if( isSet(asContext.target_requires, EstablishTrustInClient.value)
            || ( isSet(mechanism.target_requires, EstablishTrustInClient.value)
		 && !clientAuthOccurred ) ) {

            ctx = getUsernameAndPassword(ci);

            if (_logger.isLoggable(Level.FINE)) {
                _logger.log(Level.FINE, "Sending Username/Password");
            }
        } else {
            return null;
        }
        return ctx;
    
public voidsetClientConnectionContext(ConnectionContext scc)

        Hashtable h = ConnectionExecutionContext.getContext();
        h.put(CLIENT_CONNECTION_CONTEXT, scc);
    
public voidsetCtc(com.sun.enterprise.iiop.CSIV2TaggedComponentInfo val)

        this.ctc = val;
    
public voidsetMechanism(CompoundSecMech val)

        this.mechanism = val;
    
public voidsetOrb(org.omg.CORBA.ORB val)

        this.orb = val;
    
public static voidsetServerConnectionContext(ServerConnectionContext scc)

        Hashtable h = ConnectionExecutionContext.getContext();
        h.put(SERVER_CONNECTION_CONTEXT, scc);
    
private booleanskip_client_conformance(com.sun.enterprise.deployment.EjbIORConfigurationDescriptor ior)
if ejb requires no security - then skip checking the client-conformance

        String none = ior.NONE;        
	// sanity check
	if(ior == null){
	   return false;
	}
        // SSL is required and/or supported either
        if(!none.equalsIgnoreCase(ior.getIntegrity())){
            return false;
        }
        if(!none.equalsIgnoreCase(ior.getConfidentiality())){
            return false;
        }
        if(!none.equalsIgnoreCase(ior.getEstablishTrustInClient())){
            return false;
        }
        // Username password is required
        if(ior.isAuthMethodRequired()){
            return false;
        }
        // caller propagation is supported
        if(!none.equalsIgnoreCase(ior.getCallerPropagation())){
            return false;
        }
        return true;
    
private booleanuseMechanism(CompoundSecMech mech)

        boolean val = true;
        TLS_SEC_TRANS tls = ctc.getSSLInformation(mech);

        if(tls == null) {
            return true;
        }
        int targetRequires = tls.target_requires;
        if(isSet(targetRequires, EstablishTrustInClient.value)) {
            if(! SSLUtils.isKeyAvailable()) {
                val = false;
            }
        }
        return val;