TAO::SSLIOP::Connector Class Reference

SSLIOP-specific Connector bridge for pluggable protocols. More...

#include <SSLIOP_Connector.h>

Inheritance diagram for TAO::SSLIOP::Connector:

Inheritance graph
[legend]
Collaboration diagram for TAO::SSLIOP::Connector:

Collaboration graph
[legend]
List of all members.

Public Types

typedef TAO_Connect_Concurrency_Strategy<
Connection_Handler
CONNECT_CONCURRENCY_STRATEGY
typedef TAO_Connect_Creation_Strategy<
Connection_Handler
CONNECT_CREATION_STRATEGY
typedef ACE_Connect_Strategy<
Connection_Handler, ACE_SSL_SOCK_CONNECTOR > 
CONNECT_STRATEGY
typedef ACE_Strategy_Connector<
Connection_Handler, ACE_SSL_SOCK_CONNECTOR > 
BASE_CONNECTOR

Public Member Functions

 Connector (::Security::QOP qop)
 Constructor.

The TAO_Connector methods
Please check the documentation in Transport_Connector.h

virtual int open (TAO_ORB_Core *orb_core)
virtual int close (void)
virtual TAO_Transportconnect (TAO::Profile_Transport_Resolver *r, TAO_Transport_Descriptor_Interface *desc, ACE_Time_Value *timeout)
virtual TAO_Profilecreate_profile (TAO_InputCDR &cdr)
virtual int check_prefix (const char *endpoint)
virtual TAO_Profilecorbaloc_scan (const char *ior, size_t &len)

Protected Member Functions

TAO_Profilemake_secure_profile (void)
 SSL-specific profile.

TAO_Transportiiop_connect (TAO_SSLIOP_Endpoint *ssliop_endpoint, TAO::Profile_Transport_Resolver *r, ACE_Time_Value *timeout)
 IIOP-specific connection establishment.

TAO_Transportssliop_connect (TAO_SSLIOP_Endpoint *ssliop_endpoint,::Security::QOP qop, const::Security::EstablishTrust &trust, TAO::Profile_Transport_Resolver *r, TAO_Transport_Descriptor_Interface *desc, ACE_Time_Value *timeout)
 SSLIOP-specific connection establishment.

TAO::SSLIOP::OwnCredentialsretrieve_credentials (TAO_Stub *stub, SSL *ssl)
@c TAO_Connector Methods
Methods required by the TAO_Connector base class.

See also:
TAO_Connector


virtual TAO_Profilemake_profile (void)
virtual int cancel_svc_handler (TAO_Connection_Handler *svc_handler)

Private Attributes

::Security::QOP qop_
CONNECT_STRATEGY connect_strategy_
 Our connect strategy.

BASE_CONNECTOR base_connector_
 The connector initiating connection requests for IIOP.


Detailed Description

SSLIOP-specific Connector bridge for pluggable protocols.

Concrete instance of the TAO_Connector class. Responsible for establishing a connection with a server and is called from the Connector_Registry.

Definition at line 55 of file SSLIOP_Connector.h.


Member Typedef Documentation

typedef ACE_Strategy_Connector<Connection_Handler, ACE_SSL_SOCK_CONNECTOR> TAO::SSLIOP::Connector::BASE_CONNECTOR
 

Reimplemented from TAO::IIOP_SSL_Connector.

Definition at line 134 of file SSLIOP_Connector.h.

typedef TAO_Connect_Concurrency_Strategy<Connection_Handler> TAO::SSLIOP::Connector::CONNECT_CONCURRENCY_STRATEGY
 

Reimplemented from TAO::IIOP_SSL_Connector.

Definition at line 123 of file SSLIOP_Connector.h.

typedef TAO_Connect_Creation_Strategy<Connection_Handler> TAO::SSLIOP::Connector::CONNECT_CREATION_STRATEGY
 

Reimplemented from TAO::IIOP_SSL_Connector.

Definition at line 126 of file SSLIOP_Connector.h.

typedef ACE_Connect_Strategy<Connection_Handler, ACE_SSL_SOCK_CONNECTOR> TAO::SSLIOP::Connector::CONNECT_STRATEGY
 

Reimplemented from TAO::IIOP_SSL_Connector.

Definition at line 130 of file SSLIOP_Connector.h.


Constructor & Destructor Documentation

TAO_BEGIN_VERSIONED_NAMESPACE_DECL TAO::SSLIOP::Connector::Connector ::Security::QOP  qop  ) 
 

Constructor.

Definition at line 28 of file SSLIOP_Connector.cpp.

00029   : TAO::IIOP_SSL_Connector (),
00030     qop_ (qop),
00031     connect_strategy_ (),
00032     base_connector_ ()
00033 {
00034 }


Member Function Documentation

int TAO::SSLIOP::Connector::cancel_svc_handler TAO_Connection_Handler svc_handler  )  [protected, virtual]
 

Reimplemented from TAO::IIOP_SSL_Connector.

Definition at line 828 of file SSLIOP_Connector.cpp.

00830 {
00831   TAO::SSLIOP::Connection_Handler* handler=
00832     dynamic_cast<TAO::SSLIOP::Connection_Handler*> (svc_handler);
00833 
00834   if (handler)
00835     // Cancel from the connector
00836     return this->base_connector_.cancel (handler);
00837 
00838   return -1;
00839 }

int TAO::SSLIOP::Connector::check_prefix const char *  endpoint  )  [virtual]
 

Reimplemented from TAO_IIOP_Connector.

Definition at line 317 of file SSLIOP_Connector.cpp.

References ACE_OS::strchr(), ACE_OS::strlen(), and ACE_OS::strncmp().

Referenced by corbaloc_scan().

00318 {
00319   // Check for a valid string
00320   if (!endpoint || !*endpoint) return -1;  // Failure
00321 
00322   const char *protocol[] = { "ssliop", "sslioploc" };
00323 
00324   size_t first_slot = ACE_OS::strchr (endpoint, ':') - endpoint;
00325 
00326   size_t len0 = ACE_OS::strlen (protocol[0]);
00327   size_t len1 = ACE_OS::strlen (protocol[1]);
00328 
00329   // Check for the proper prefix in the IOR.  If the proper prefix
00330   // isn't in the IOR then it is not an IOR we can use.
00331   if (first_slot == len0 && ACE_OS::strncmp (endpoint, protocol[0], len0) == 0)
00332     return 0;
00333 
00334   if (first_slot == len1 && ACE_OS::strncmp (endpoint, protocol[1], len1) == 0)
00335     return 0;
00336 
00337   // Failure: not an SSLIOP IOR
00338   // DO NOT throw an exception here.
00339   return -1;
00340 }

int TAO::SSLIOP::Connector::close void   )  [virtual]
 

Reimplemented from TAO::IIOP_SSL_Connector.

Definition at line 75 of file SSLIOP_Connector.cpp.

References TAO::IIOP_SSL_Connector::close().

00076 {
00077   (void) this->TAO::IIOP_SSL_Connector::close ();
00078 
00079   delete this->base_connector_.creation_strategy ();
00080   delete this->base_connector_.concurrency_strategy ();
00081   return this->base_connector_.close ();
00082 }

TAO_Transport * TAO::SSLIOP::Connector::connect TAO::Profile_Transport_Resolver r,
TAO_Transport_Descriptor_Interface desc,
ACE_Time_Value timeout
[virtual]
 

Reimplemented from TAO_Connector.

Definition at line 85 of file SSLIOP_Connector.cpp.

References CORBA::Policy::_narrow(), ACE_DEBUG, ACE_ERROR, ACE_TEXT(), TAO_Transport_Descriptor_Interface::endpoint(), TAO_Stub::get_policy(), iiop_connect(), CORBA::is_nil(), LM_DEBUG, LM_ERROR, TAO_SSLIOP_Endpoint::ssl_component(), ssliop_connect(), TAO::Profile_Transport_Resolver::stub(), TAO_Endpoint::tag(), and TAO_debug_level.

00088 {
00089   if (TAO_debug_level > 0)
00090       ACE_DEBUG ((LM_DEBUG,
00091                   ACE_TEXT ("TAO_SSLIOP (%P|%t) - Connector::connect, ")
00092                   ACE_TEXT ("looking for SSLIOP connection.\n")));
00093 
00094   TAO_Endpoint *endpoint = desc->endpoint ();
00095 
00096   if (endpoint->tag () != IOP::TAG_INTERNET_IOP)
00097     return 0;
00098 
00099   TAO_SSLIOP_Endpoint *ssl_endpoint =
00100     dynamic_cast<TAO_SSLIOP_Endpoint *> (endpoint);
00101 
00102   if (ssl_endpoint == 0)
00103     return 0;
00104 
00105   // @@ TODO:  The EstablishTrust policy should be evaluated once per
00106   //           connection, not once per invocation.  This should
00107   //           improve performance.
00108   //
00109   // Check if the user overrode the default establishment of trust
00110   // policy for the current object.
00111   CORBA::Policy_var policy =
00112     resolver->stub ()->get_policy (::Security::SecEstablishTrustPolicy);
00113 
00114   SecurityLevel2::EstablishTrustPolicy_var trust_policy =
00115     SecurityLevel2::EstablishTrustPolicy::_narrow (policy.in ());
00116 
00117   // We use a pointer and temporary to make it obvious to determine
00118   // if no establishment of trust policy was set.  Specifically, if
00119   // the "trust" pointer below is zero, then the SSLIOP pluggable
00120   // protocol default value will be used.
00121   ::Security::EstablishTrust trust = { 0 , 0 };
00122   if (!CORBA::is_nil (trust_policy.in ()))
00123     {
00124       trust = trust_policy->trust ();
00125     }
00126 
00127   // Flag that states whether any form of establishment of trust
00128   // should occur.
00129   CORBA::Boolean const establish_trust =
00130     trust.trust_in_target || trust.trust_in_client;
00131 
00132   // @@ Should this be in a "policy validator?"
00133   //
00134   // If the SSL port is zero, then no SSLIOP tagged component was
00135   // available in the IOR, meaning that there is no way to establish
00136   // trust.  Throw an exception.
00137   if (ssl_endpoint->ssl_component ().port == 0
00138       && establish_trust)
00139     {
00140       if (TAO_debug_level > 0)
00141         {
00142           ACE_ERROR ((LM_ERROR,
00143                       ACE_TEXT ("TAO_SSLIOP (%P|%t) ERROR: ")
00144                       ACE_TEXT ("Cannot establish trust since ")
00145                       ACE_TEXT ("no SSLIOP tagged component was ")
00146                       ACE_TEXT ("found in the IOR.\n")));
00147         }
00148 
00149       throw CORBA::INV_POLICY ();
00150     }
00151 
00152   // Check if the user overrode the default Quality-of-Protection for
00153   // the current object.
00154   policy = resolver->stub ()->get_policy (::Security::SecQOPPolicy);
00155 
00156   SecurityLevel2::QOPPolicy_var qop_policy =
00157     SecurityLevel2::QOPPolicy::_narrow (policy.in ());
00158 
00159   // Temporary variable used to avoid overwriting the default value
00160   // set when the ORB was initialized.
00161   ::Security::QOP qop = this->qop_;
00162 
00163   if (!CORBA::is_nil (qop_policy.in ()))
00164     {
00165       qop = qop_policy->qop ();
00166     }
00167 
00168   // If the SSL port is zero, then no SSLIOP tagged component was
00169   // available in the IOR, meaning that there is no way to make a
00170   // secure invocation.  Throw an exception.
00171   if (qop != ::Security::SecQOPNoProtection
00172       && ssl_endpoint->ssl_component ().port == 0)
00173     {
00174       if (TAO_debug_level > 0)
00175         {
00176           ACE_ERROR ((LM_ERROR,
00177                       ACE_TEXT ("TAO_SSLIOP (%P|%t) ERROR: ")
00178                       ACE_TEXT ("Cannot make secure invocation since ")
00179                       ACE_TEXT ("no SSLIOP tagged component was ")
00180                       ACE_TEXT ("found in the IOR.\n")));
00181         }
00182 
00183       throw CORBA::INV_POLICY ();
00184     }
00185 
00186   if ((!establish_trust && qop == ::Security::SecQOPNoProtection)
00187       || ssl_endpoint->ssl_component ().port == 0)
00188     {
00189       return this->iiop_connect (ssl_endpoint, resolver, timeout);
00190     }
00191 
00192   return this->ssliop_connect (ssl_endpoint,
00193                                qop,
00194                                trust,
00195                                resolver,
00196                                desc,
00197                                timeout);
00198 }

TAO_Profile * TAO::SSLIOP::Connector::corbaloc_scan const char *  ior,
size_t &  len
[virtual]
 

Reimplemented from TAO_Connector.

Definition at line 264 of file SSLIOP_Connector.cpp.

References ACE_DEBUG, ACE_TEXT, TAO_IIOP_Connector::check_prefix(), check_prefix(), LM_DEBUG, make_profile(), make_secure_profile(), ACE_OS::strchr(), ACE_OS::strlen(), and TAO_debug_level.

00265 {
00266    int ssl_only = 0;
00267    if (this->check_prefix (endpoint) == 0)
00268    {
00269        ssl_only = 1;
00270    }
00271    else
00272    {
00273        if (this->TAO_IIOP_Connector::check_prefix (endpoint) != 0)
00274          return 0;
00275    }
00276 
00277    // Determine the (first in a list of possibly > 1) endpoint address
00278    const char *comma_pos = ACE_OS::strchr (endpoint,',');
00279    const char *slash_pos = ACE_OS::strchr (endpoint,'/');
00280    if (comma_pos == 0 && slash_pos == 0)
00281    {
00282        if (TAO_debug_level)
00283        {
00284             ACE_DEBUG ((LM_DEBUG,
00285                         ACE_TEXT("(%P|%t) SSLIOP_Connector::corbaloc_scan warning: ")
00286                         ACE_TEXT("supplied string contains no comma or slash: %s\n"),
00287                         endpoint));
00288        }
00289        len = ACE_OS::strlen (endpoint);
00290    }
00291    else if (slash_pos != 0 || comma_pos > slash_pos)
00292    {
00293        // The endpoint address does not extend past the first '/' or ','
00294        len = slash_pos - endpoint;
00295    }
00296    else
00297    {
00298        len = comma_pos - endpoint;
00299    }
00300 
00301    //Create the corresponding profile
00302    TAO_Profile *ptmp = 0;
00303    if (ssl_only)
00304      {
00305        ptmp = this->make_secure_profile ();
00306      }
00307    else
00308      {
00309        ptmp = this->make_profile ();
00310      }
00311 
00312    return ptmp;
00313 }

TAO_Profile * TAO::SSLIOP::Connector::create_profile TAO_InputCDR cdr  )  [virtual]
 

Reimplemented from TAO_IIOP_Connector.

Definition at line 202 of file SSLIOP_Connector.cpp.

References TAO_Profile::_decr_refcnt(), ACE_NEW_RETURN, and TAO_Profile::decode().

00203 {
00204   TAO_Profile *pfile = 0;
00205   ACE_NEW_RETURN (pfile,
00206                   TAO_SSLIOP_Profile (this->orb_core ()),
00207                   0);
00208 
00209   if (pfile->decode (cdr) == -1)
00210     {
00211       pfile->_decr_refcnt ();
00212       pfile = 0;
00213     }
00214 
00215   return pfile;
00216 }

TAO_Transport * TAO::SSLIOP::Connector::iiop_connect TAO_SSLIOP_Endpoint ssliop_endpoint,
TAO::Profile_Transport_Resolver r,
ACE_Time_Value timeout
[protected]
 

IIOP-specific connection establishment.

Note:
The IIOP endpoint is extracted from the SSLIOP endpoint.

Definition at line 344 of file SSLIOP_Connector.cpp.

References ACE_BIT_DISABLED, TAO_Connector::connect(), EPERM, TAO_SSLIOP_Endpoint::iiop_endpoint(), and TAO_SSLIOP_Endpoint::ssl_component().

Referenced by connect().

00348 {
00349 #if 0
00350   const ::SSLIOP::SSL &ssl_component = ssl_endpoint->ssl_component ();
00351 
00352   // Only allow connection to the insecure IIOP port if the endpoint
00353   // explicitly allows it, i.e. if the Security::NoProtection security
00354   // association bit is set in the SSLIOP::SSL::target_supports field.
00355   // The server performs the same permission check, so this check is
00356   // an optimization since a connection will not be established
00357   // needlessly, i.e. rejected due to lack of permission.
00358   //
00359   // Note that it is still possible for the standard non-SSLIOP aware
00360   // IIOP pluggable protocol to attempt to connect to the insecure
00361   // port.  In that case, the server will have to prevent the
00362   // connection, and subsequently the request, from completing.
00363   if (ACE_BIT_DISABLED (ssl_component.target_supports,
00364                         ::Security::NoProtection))
00365     throw CORBA::NO_PERMISSION (
00366       CORBA::SystemException::_tao_minor_code (
00367         TAO::VMCID,
00368         EPERM),
00369       CORBA::COMPLETED_NO);
00370 #endif
00371 
00372   TAO_IIOP_Endpoint *iiop_endpoint = ssl_endpoint->iiop_endpoint ();
00373 
00374   // An IIOP-only transport descriptor must be used instead of the one
00375   // passed to this method since the latter is used for SSLIOP
00376   // connections.  Doing so prevents an IIOP-only cached transport
00377   // from being associated with an SSLIOP connection.
00378   TAO_Base_Transport_Property iiop_desc (iiop_endpoint);
00379 
00380   // Note that the IIOP-only transport descriptor is used!
00381   return
00382     this->TAO::IIOP_SSL_Connector::connect (resolver, &iiop_desc, timeout);
00383 }

TAO_Profile * TAO::SSLIOP::Connector::make_profile void   )  [protected, virtual]
 

Reimplemented from TAO_IIOP_Connector.

Definition at line 219 of file SSLIOP_Connector.cpp.

References ACE_NEW_THROW_EX.

Referenced by corbaloc_scan().

00220 {
00221   // The endpoint should be of the form:
00222   //    N.n@host:port/object_key
00223   // or:
00224   //    host:port/object_key
00225 
00226   TAO_Profile *profile = 0;
00227   ACE_NEW_THROW_EX (profile,
00228                     TAO_SSLIOP_Profile (this->orb_core (),
00229                                           0), // SSL component
00230                     CORBA::NO_MEMORY (
00231                       CORBA::SystemException::_tao_minor_code (
00232                         TAO::VMCID,
00233                         ENOMEM),
00234                       CORBA::COMPLETED_NO));
00235 
00236   return profile;
00237 }

TAO_Profile * TAO::SSLIOP::Connector::make_secure_profile void   )  [protected]
 

SSL-specific profile.

Definition at line 241 of file SSLIOP_Connector.cpp.

References ACE_NEW_THROW_EX.

Referenced by corbaloc_scan().

00242 {
00243   // The endpoint should be of the form:
00244   //    N.n@host:port/object_key
00245   // or:
00246   //    host:port/object_key
00247 
00248   TAO_Profile *profile = 0;
00249   ACE_NEW_THROW_EX (profile,
00250                     TAO_SSLIOP_Profile (this->orb_core (),
00251                                           1), // SSL component
00252                     CORBA::NO_MEMORY (
00253                       CORBA::SystemException::_tao_minor_code (
00254                         TAO::VMCID,
00255                         ENOMEM),
00256                       CORBA::COMPLETED_NO));
00257 
00258   return profile;
00259 }

int TAO::SSLIOP::Connector::open TAO_ORB_Core orb_core  )  [virtual]
 

Reimplemented from TAO::IIOP_SSL_Connector.

Definition at line 37 of file SSLIOP_Connector.cpp.

References ACE_NEW_RETURN, TAO::IIOP_SSL_Connector::open(), TAO_Connector::orb_core(), TAO_ORB_Core::reactor(), and TAO_ORB_Core::thr_mgr().

00038 {
00039   // Since the ACE_Strategy_Connector (and ACE_Connector) cannot
00040   // handle non-blocking connections with protocols that have more
00041   // than one handshake, such as SSL, force blocking connections for
00042   // SSLIOP.  This deficiency will be addressed soon.
00043   ACE_NEW_RETURN (this->active_connect_strategy_,
00044                   TAO_Blocked_Connect_Strategy (orb_core),
00045                   -1);
00046 
00047   if (this->TAO::IIOP_SSL_Connector::open (orb_core) == -1)
00048     return -1;
00049 
00050   // Our connect creation strategy
00051   CONNECT_CREATION_STRATEGY *connect_creation_strategy = 0;
00052 
00053   ACE_NEW_RETURN (connect_creation_strategy,
00054                   CONNECT_CREATION_STRATEGY
00055                       (orb_core->thr_mgr (),
00056                        orb_core),
00057                   -1);
00058 
00059   // Our activation strategy
00060   CONNECT_CONCURRENCY_STRATEGY *concurrency_strategy = 0;
00061 
00062   ACE_NEW_RETURN (concurrency_strategy,
00063                   CONNECT_CONCURRENCY_STRATEGY (orb_core),
00064                   -1);
00065 
00066   ACE_Reactor *r = this->orb_core ()->reactor ();
00067 
00068   return this->base_connector_.open (r,
00069                                      connect_creation_strategy,
00070                                      &this->connect_strategy_,
00071                                      concurrency_strategy);
00072 }

TAO::SSLIOP::OwnCredentials * TAO::SSLIOP::Connector::retrieve_credentials TAO_Stub stub,
SSL *  ssl
[protected]
 

Retrieve SSLIOP credentials from the policy overrides list and set up the underlying SSL connection to use the X.509 certificates stored within them.

Todo:
Check if the CredentialsCurator contains a default set of SSLIOP OwnCredentials.

Definition at line 759 of file SSLIOP_Connector.cpp.

References TAO::SSLIOP::OwnCredentials::_narrow(), TAO::SSLIOP::OwnCredentials::_nil(), TAO_Pseudo_Var_T< T >::_retn(), ACE_NEW_THROW_EX, TAO::SSLIOP::EVP_PKEY_var, TAO_Stub::get_policy(), TAO::SSLIOP::OpenSSL_st_var< T >::in(), TAO_Pseudo_Var_T< T >::in(), CORBA::is_nil(), TAO_Pseudo_Var_T< T >::out(), TAO::SSLIOP::OwnCredentials_ptr, TAO::SSLIOP::OwnCredentials_var, and TAO::SSLIOP::X509_var.

Referenced by ssliop_connect().

00761 {
00762   // Check if the user overrode the default invocation credentials.
00763   CORBA::Policy_var policy =
00764     stub->get_policy (::SecurityLevel3::ContextEstablishmentPolicyType);
00765 
00766   SecurityLevel3::ContextEstablishmentPolicy_var creds_policy =
00767     SecurityLevel3::ContextEstablishmentPolicy::_narrow (
00768       policy.in ());
00769 
00770   TAO::SSLIOP::OwnCredentials_var ssliop_credentials;
00771 
00772   // Set the Credentials (X.509 certificates and corresponding private
00773   // keys) to be used for this invocation.
00774   if (!CORBA::is_nil (creds_policy.in ()))
00775     {
00776       SecurityLevel3::OwnCredentialsList_var creds_list =
00777         creds_policy->creds_list ();
00778 
00779       if (creds_list->length () > 0)
00780         {
00781           // Assume that we've got an SSLIOP credential.
00782           SecurityLevel3::Credentials_ptr credentials =
00783             creds_list[0u];
00784 
00785           ssliop_credentials =
00786             TAO::SSLIOP::OwnCredentials::_narrow (credentials);
00787 
00788           if (!CORBA::is_nil (ssliop_credentials.in ()))
00789             {
00790               TAO::SSLIOP::X509_var x509 = ssliop_credentials->x509 ();
00791               if (::SSL_use_certificate (ssl, x509.in ()) != 1)
00792                 return TAO::SSLIOP::OwnCredentials::_nil ();
00793 
00794               TAO::SSLIOP::EVP_PKEY_var evp = ssliop_credentials->evp ();
00795               if (evp.in () != 0
00796                   && ::SSL_use_PrivateKey (ssl, evp.in ()) != 1)
00797                 {
00798                   // Invalidate the certificate we just set.
00799                   (void) ::SSL_use_certificate (ssl, 0);
00800                   return TAO::SSLIOP::OwnCredentials::_nil ();
00801                 }
00802             }
00803         }
00804     }
00805   else
00806     {
00807       // Use the default certificate and private key, i.e. the one set
00808       // in the SSL_CTX that was used when creating the SSL data
00809       // structure.
00810 
00811       /**
00812        * @todo Check if the CredentialsCurator contains a default set
00813        *       of SSLIOP OwnCredentials.
00814        */
00815 
00816       TAO::SSLIOP::OwnCredentials_ptr & c = ssliop_credentials.out ();
00817       ACE_NEW_THROW_EX (c,
00818                         TAO::SSLIOP::OwnCredentials (
00819                           ::SSL_get_certificate (ssl),
00820                           ::SSL_get_privatekey (ssl)),
00821                         CORBA::NO_MEMORY ());
00822     }
00823 
00824   return ssliop_credentials._retn ();
00825 }

TAO_Transport * TAO::SSLIOP::Connector::ssliop_connect TAO_SSLIOP_Endpoint ssliop_endpoint,
::Security::QOP  qop,
const::Security::EstablishTrust &  trust,
TAO::Profile_Transport_Resolver r,
TAO_Transport_Descriptor_Interface desc,
ACE_Time_Value timeout
[protected]
 

SSLIOP-specific connection establishment.

Definition at line 386 of file SSLIOP_Connector.cpp.

References ACE_BIT_DISABLED, ACE_BIT_ENABLED, ACE_DEBUG, ACE_ERROR, ACE_TEXT(), TAO_SSLIOP_Endpoint::addr_to_string(), AF_INET, TAO_Connection_Handler::cancel_pending_connection(), TAO::SSLIOP::Connection_Handler::close(), TAO_Transport::close_connection(), TAO_Connection_Handler::connection_pending(), TAO_SSLIOP_Endpoint::credentials_set(), EPERM, TAO_LF_CH_Event::error_detected(), EWOULDBLOCK, TAO::Transport_Cache_Manager::find_transport(), ACE_INET_Addr::get_port_number(), ACE_Addr::get_type(), TAO_Transport::id(), TAO_Pseudo_Var_T< T >::in(), TAO_Transport::is_connected(), TAO_LF_Event::keep_waiting(), TAO_ORB_Core::lane_resources(), LM_DEBUG, LM_ERROR, MAXHOSTNAMELEN, TAO_SSLIOP_Endpoint::object_addr(), TAO_Connector::orb_core(), TAO::SSLIOP::OwnCredentials_var, ACE_Svc_Handler<, >::peer(), TAO::Transport_Cache_Manager::purge(), TAO_Transport::purge_entry(), TAO_Wait_Strategy::register_handler(), ACE_Auto_Basic_Ptr< X >::release(), ACE_Event_Handler::remove_reference(), retrieve_credentials(), TAO_SSLIOP_Endpoint::set_sec_attrs(), TAO_SSLIOP_Endpoint::ssl_component(), TAO::Profile_Transport_Resolver::stub(), TAO_Connect_Strategy::synch_options(), TAO_debug_level, TAO_Connection_Handler::transport(), TAO_Thread_Lane_Resources::transport_cache(), Security::EstablishTrust::trust_in_client, Security::EstablishTrust::trust_in_target, TAO_Connector::wait_for_connection_completion(), and TAO_Transport::wait_strategy().

Referenced by connect().

00393 {
00394   const ::SSLIOP::SSL &ssl_component = ssl_endpoint->ssl_component ();
00395 
00396   // @@ The following check for "required insecurity" seems odd, but
00397   //    I haven't seen anything in the Security spec that says this
00398   //    policy isn't possible.
00399   //      -Ossama
00400 
00401   // If the endpoint requires an insecure connection, i.e. the
00402   // Security::NoProtection security association bit in the
00403   // SSLIOP::SSL::target_requires field is enabled, then prevent an
00404   // SSL connection from occuring.
00405   if (ACE_BIT_ENABLED (ssl_component.target_requires,
00406                        ::Security::NoProtection))
00407     throw CORBA::NO_PERMISSION (
00408       CORBA::SystemException::_tao_minor_code (
00409         TAO::VMCID,
00410         EPERM),
00411       CORBA::COMPLETED_NO);
00412 
00413   // If the invocation wants integrity without confidentiality but the
00414   // server does not support "no protection," then it won't be
00415   // possible to provide integrity.  In order to support integrity
00416   // without confidentiality, encryption must be disabled but secure
00417   // hashes must remain enabled.  This is achieved using the "eNULL"
00418   // cipher.  However, the "eNULL" cipher is only enabled on the
00419   // server side if "no protection" is enabled.
00420   if (ACE_BIT_DISABLED (ssl_component.target_supports,
00421                         ::Security::NoProtection)
00422       && qop == ::Security::SecQOPIntegrity)
00423     throw CORBA::INV_POLICY ();
00424 
00425   const ACE_INET_Addr &remote_address = ssl_endpoint->object_addr ();
00426 
00427   // Verify that the remote ACE_INET_Addr was initialized
00428   // properly.  Failure can occur if hostname lookup failed when
00429   // initializing the remote ACE_INET_Addr.
00430   if (remote_address.get_type () != AF_INET
00431 #if defined (ACE_HAS_IPV6)
00432       && remote_address.get_type () != AF_INET6
00433 #endif /* ACE_HAS_IPV6 */
00434       )
00435     {
00436       if (TAO_debug_level > 0)
00437         {
00438           ACE_DEBUG ((LM_DEBUG,
00439                       ACE_TEXT ("TAO (%P|%t) SSLIOP connection failed.\n")
00440                       ACE_TEXT ("TAO (%P|%t) This is most likely ")
00441                       ACE_TEXT ("due to a hostname lookup ")
00442                       ACE_TEXT ("failure.\n")));
00443         }
00444 
00445       return 0;
00446     }
00447 
00448   int result = 0;
00449   TAO::SSLIOP::Connection_Handler *svc_handler = 0;
00450   TAO_Transport *transport = 0;
00451 
00452   // Before we can check the cache to find an existing connection, we
00453   // need to make sure the ssl_endpoint is fully initialized with the
00454   // local security information. This endpoint initalized by the
00455   // profile does not (and cannot) contain the desired QOP, trust, or
00456   // credential information which is necesary to uniquely identify
00457   // this connection.
00458   if (!ssl_endpoint->credentials_set ())
00459     {
00460       if (TAO_debug_level > 2)
00461         ACE_DEBUG ((LM_ERROR,
00462                     ACE_TEXT ("TAO (%P|%t) Initializing SSLIOP_Endpoint \n")
00463                     ));
00464 
00465       if (this->base_connector_.creation_strategy ()->make_svc_handler (
00466                svc_handler) != 0)
00467         {
00468           if (TAO_debug_level > 0)
00469             ACE_DEBUG ((LM_ERROR,
00470                         ACE_TEXT ("TAO (%P|%t) Unable to create SSLIOP ")
00471                         ACE_TEXT ("service handler.\n")));
00472 
00473           return 0;
00474         }
00475 
00476       ACE_Auto_Basic_Ptr<TAO::SSLIOP::Connection_Handler>
00477         safe_handler (svc_handler);
00478       TAO::SSLIOP::OwnCredentials_var credentials =
00479         this->retrieve_credentials (resolver->stub (),
00480                                     svc_handler->peer ().ssl ());
00481 
00482       svc_handler = safe_handler.release ();
00483       ssl_endpoint->set_sec_attrs (qop, trust, credentials.in());
00484     }
00485 
00486   // Check the Cache first for connections
00487   if (this->orb_core ()->lane_resources ().transport_cache ().find_transport (
00488         desc,
00489         transport) == 0)
00490     {
00491       if (TAO_debug_level > 2)
00492         ACE_DEBUG ((LM_DEBUG,
00493                     ACE_TEXT ("TAO (%P|%t) - SSLIOP_Connector::ssliop_connect, ")
00494                     ACE_TEXT ("got existing transport[%d]\n"),
00495                     transport->id ()));
00496 
00497       // When the transport is not connected wait for completion
00498       if (!transport->is_connected())
00499         {
00500           if (!this->wait_for_connection_completion (resolver,
00501                                                      transport,
00502                                                      max_wait_time))
00503             {
00504               ACE_ERROR ((LM_ERROR,
00505                           ACE_TEXT ("TAO (%P|%t) - SSLIOP_Connector::ssliop_connect,")
00506                           ACE_TEXT ("wait for completion failed\n")));
00507 
00508             }
00509         }
00510     }
00511   else
00512     {
00513       if (TAO_debug_level > 4)
00514         ACE_DEBUG ((LM_DEBUG,
00515                     ACE_TEXT ("TAO (%P|%t) - SSLIOP_Connector::ssliop_connect, ")
00516                     ACE_TEXT ("making a new connection \n")));
00517 
00518       // Purge connections (if necessary)
00519       this->orb_core ()->lane_resources ().transport_cache ().purge ();
00520 
00521       // The svc_handler is created beforehand so that we can get
00522       // access to the underlying ACE_SSL_SOCK_Stream (the peer) and
00523       // its SSL pointer member prior to descending into the
00524       // ACE_Strategy_Connector (the "base_connector_").  This is
00525       // thread-safe and reentrant, hence no synchronization is
00526       // necessary.
00527       //
00528       // The make_svc_handler() method creates the service handler and
00529       // bumps the #REFCOUNT# up one extra.  The extra reference count
00530       // in TAO_Connect_Creation_Strategy::make_svc_handler() is
00531       // needed in the case when connection completion is pending and
00532       // we are going to wait on a variable in the handler to changes,
00533       // signifying success or failure.  Note, that this increment
00534       // cannot be done once the connect() returns since this might be
00535       // too late if another thread pick up the completion and
00536       // potentially deletes the handler before we get a chance to
00537       // increment the reference count.
00538       if (svc_handler == 0 &&
00539           this->base_connector_.creation_strategy ()->make_svc_handler (
00540                svc_handler) != 0)
00541         {
00542           if (TAO_debug_level > 0)
00543             ACE_DEBUG ((LM_ERROR,
00544                         ACE_TEXT ("TAO (%P|%t) Unable to create SSLIOP ")
00545                         ACE_TEXT ("service handler.\n")));
00546 
00547           return 0;
00548         }
00549 
00550       ACE_Auto_Basic_Ptr<TAO::SSLIOP::Connection_Handler>
00551         safe_handler (svc_handler);
00552 
00553       // Setup the establishment of trust connection properties, if
00554       // any.
00555       int verify_mode = 0;
00556 
00557       // On the server side, "trust_in_client" requires that a peer
00558       // (client) certificate exist.  Fail if one doesn't exist.
00559       //
00560       // In SSLIOP's case, trust_in_client also implies
00561       // trust_in_target.
00562       if (trust.trust_in_client)
00563         verify_mode = SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
00564 
00565       // Require verification of the target's certificate.
00566       else if (trust.trust_in_target)
00567         verify_mode = SSL_VERIFY_PEER;
00568 
00569       // Trust in neither the client nor the target is explicitly
00570       // specified.  Use the default setting.
00571       else
00572         verify_mode = ACE_SSL_Context::instance ()->default_verify_mode ();
00573 
00574       ::SSL_set_verify (svc_handler->peer ().ssl (),
00575                         verify_mode,
00576                         0);
00577 
00578       // The "eNULL" cipher disables encryption but still uses a
00579       // secure hash (e.g. SHA1 or MD5) to ensure integrity.  (Try the
00580       // command "openssl ciphers -v eNULL".)
00581       //
00582       // Note that it is not possible to completely disable protection
00583       // here.
00584       if ((qop == ::Security::SecQOPNoProtection
00585           || qop == ::Security::SecQOPIntegrity)
00586           && ::SSL_set_cipher_list (svc_handler->peer ().ssl (),
00587                                     "eNULL") == 0)
00588         {
00589           if (TAO_debug_level > 0)
00590             ACE_DEBUG ((LM_ERROR,
00591                         ACE_TEXT ("(%P|%t) Unable to set eNULL ")
00592                         ACE_TEXT ("SSL cipher.\n")));
00593 
00594           throw CORBA::INV_POLICY ();
00595         }
00596 
00597       svc_handler = safe_handler.release ();
00598 
00599       // Get the right synch options
00600       ACE_Synch_Options synch_options;
00601 
00602       this->active_connect_strategy_->synch_options (max_wait_time,
00603                                                      synch_options);
00604 
00605       // The code used to set the timeout to zero, with the intent of
00606       // polling the reactor for connection completion. However, the side-effect
00607       // was to cause the connection to timeout immediately.
00608 
00609       // We obtain the transport in the <svc_handler> variable.  As we
00610       // know now that the connection is not available in Cache we can
00611       // make a new connection
00612       result = this->base_connector_.connect (svc_handler,
00613                                               remote_address,
00614                                               synch_options);
00615 
00616       // base_connector_.connect() will increment the handler's
00617       // #REFCOUNT# once more. This is not required as we already hold
00618       // a reference to the handler, so we discard this second
00619       // reference.
00620       svc_handler->remove_reference ();
00621 
00622       // There are three possibilities from calling connect(): (a)
00623       // connection succeeds immediately - in this case, the
00624       // #REFCOUNT# on the handler is two; (b) connection completion
00625       // is pending - in this case, the #REFCOUNT# on the handler is
00626       // also two; (c) connection fails immediately - in this case,
00627       // the #REFCOUNT# on the handler is one since close() gets
00628       // called on the handler.
00629 
00630       // Make sure that we always do a remove_reference
00631       ACE_Event_Handler_var svc_handler_auto_ptr (svc_handler);
00632 
00633       transport =
00634         svc_handler->transport ();
00635 
00636       if (result == -1)
00637         {
00638           // No immediate result, wait for completion
00639           if (errno == EWOULDBLOCK)
00640             {
00641               // Try to wait until connection completion. Incase we block, then we
00642               // get a connected transport or not. In case of non block we get
00643               // a connected or not connected transport
00644               if (!this->wait_for_connection_completion (resolver,
00645                                                          transport,
00646                                                          max_wait_time))
00647                 {
00648                   if (TAO_debug_level > 2)
00649                     ACE_ERROR ((LM_ERROR, "TAO (%P|%t) - SSLIOP_Connector::"
00650                                           "ssliop_connect, "
00651                                           "wait for completion failed\n"));
00652                 }
00653             }
00654           else
00655             {
00656               // Transport is not usable
00657               transport = 0;
00658             }
00659         }
00660 
00661       // In case of errors transport is zero
00662       if (transport == 0)
00663         {
00664           // Give users a clue to the problem.
00665           if (TAO_debug_level)
00666             {
00667               char buffer [MAXHOSTNAMELEN + 6 + 1];
00668               ssl_endpoint->addr_to_string (buffer,
00669                                             sizeof (buffer) - 1);
00670               ACE_DEBUG ((LM_ERROR,
00671                           ACE_TEXT ("TAO (%P|%t) - SSL connection to ")
00672                           ACE_TEXT ("<%s:%d> failed (%p)\n"),
00673                           buffer,
00674                           remote_address.get_port_number (),
00675                           ACE_TEXT ("errno")));
00676             }
00677 
00678           return 0;
00679         }
00680 
00681       // fix for bug 2654
00682       if (svc_handler->keep_waiting ())
00683         {
00684           svc_handler->connection_pending ();
00685         }
00686 
00687       // fix for bug 2654
00688       if (svc_handler->error_detected ())
00689         {
00690           svc_handler->cancel_pending_connection ();
00691         }
00692 
00693       // At this point, the connection has be successfully connected.
00694       // #REFCOUNT# is one.
00695       if (TAO_debug_level > 2)
00696         ACE_DEBUG ((LM_DEBUG,
00697                     "TAO (%P|%t) - SSLIOP_Connector::ssliop_connect, "
00698                     "new SSL connection to port %d on transport[%d]\n",
00699                     remote_address.get_port_number (),
00700                     svc_handler->peer ().get_handle ()));
00701 
00702       // Add the handler to Cache
00703       int retval =
00704         this->orb_core ()->
00705           lane_resources ().transport_cache ().cache_transport (desc,
00706                                                                 transport);
00707 
00708       // Failure in adding to cache.
00709       if (retval != 0)
00710         {
00711           // Close the handler.
00712           svc_handler->close ();
00713 
00714           if (TAO_debug_level > 0)
00715             {
00716               ACE_ERROR ((LM_ERROR,
00717                           "TAO (%P|%t) - SLIIOP_Connector::ssliop_connect, "
00718                           "could not add the new connection to cache\n"));
00719             }
00720 
00721           return 0;
00722         }
00723 
00724       // fix for bug 2654
00725       if (svc_handler->error_detected ())
00726         {
00727           svc_handler->cancel_pending_connection ();
00728           transport->purge_entry();
00729           return 0;
00730         }
00731 
00732       if (transport->is_connected () &&
00733           transport->wait_strategy ()->register_handler () != 0)
00734         {
00735           // Registration failures.
00736 
00737           // Purge from the connection cache, if we are not in the cache, this
00738           // just does nothing.
00739           (void) transport->purge_entry ();
00740 
00741           // Close the handler.
00742           (void) transport->close_connection ();
00743 
00744           if (TAO_debug_level > 0)
00745             ACE_ERROR ((LM_ERROR,
00746                         "TAO (%P|%t) - SSLIOP_Connector [%d]::ssliop_connect, "
00747                         "could not register the transport "
00748                         "in the reactor.\n",
00749                         transport->id ()));
00750 
00751           return 0;
00752         }
00753     }
00754 
00755   return transport;
00756 }


Member Data Documentation

BASE_CONNECTOR TAO::SSLIOP::Connector::base_connector_ [private]
 

The connector initiating connection requests for IIOP.

Reimplemented from TAO::IIOP_SSL_Connector.

Definition at line 146 of file SSLIOP_Connector.h.

CONNECT_STRATEGY TAO::SSLIOP::Connector::connect_strategy_ [private]
 

Our connect strategy.

Reimplemented from TAO::IIOP_SSL_Connector.

Definition at line 143 of file SSLIOP_Connector.h.

::Security::QOP TAO::SSLIOP::Connector::qop_ [private]
 

If zero, connect to IIOP over SSL port by default. Otherwise, connect to the insecure IIOP port.

Definition at line 140 of file SSLIOP_Connector.h.


The documentation for this class was generated from the following files:
Generated on Sun Jan 27 16:14:16 2008 for TAO_SSLIOP by doxygen 1.3.6