#include <SSLIOP_Connector.h>
Collaboration diagram for TAO::SSLIOP::Connector:
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 | |
virtual int | open (TAO_ORB_Core *orb_core) |
virtual int | close (void) |
virtual TAO_Transport * | connect (TAO::Profile_Transport_Resolver *r, TAO_Transport_Descriptor_Interface *desc, ACE_Time_Value *timeout) |
virtual TAO_Profile * | create_profile (TAO_InputCDR &cdr) |
virtual int | check_prefix (const char *endpoint) |
virtual TAO_Profile * | corbaloc_scan (const char *ior, size_t &len) |
Protected Member Functions | |
TAO_Profile * | make_secure_profile (void) |
SSL-specific profile. | |
TAO_Transport * | iiop_connect (TAO_SSLIOP_Endpoint *ssliop_endpoint, TAO::Profile_Transport_Resolver *r, ACE_Time_Value *timeout) |
IIOP-specific connection establishment. | |
TAO_Transport * | 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) |
SSLIOP-specific connection establishment. | |
TAO::SSLIOP::OwnCredentials * | retrieve_credentials (TAO_Stub *stub, SSL *ssl) |
@c TAO_Connector Methods | |
virtual TAO_Profile * | make_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. |
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.
typedef ACE_Strategy_Connector<Connection_Handler, ACE_SSL_SOCK_CONNECTOR> TAO::SSLIOP::Connector::BASE_CONNECTOR |
Definition at line 132 of file SSLIOP_Connector.h.
typedef TAO_Connect_Concurrency_Strategy<Connection_Handler> TAO::SSLIOP::Connector::CONNECT_CONCURRENCY_STRATEGY |
Definition at line 121 of file SSLIOP_Connector.h.
typedef TAO_Connect_Creation_Strategy<Connection_Handler> TAO::SSLIOP::Connector::CONNECT_CREATION_STRATEGY |
Definition at line 124 of file SSLIOP_Connector.h.
typedef ACE_Connect_Strategy<Connection_Handler, ACE_SSL_SOCK_CONNECTOR> TAO::SSLIOP::Connector::CONNECT_STRATEGY |
Definition at line 128 of file SSLIOP_Connector.h.
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 }
int TAO::SSLIOP::Connector::cancel_svc_handler | ( | TAO_Connection_Handler * | svc_handler | ) | [protected, virtual] |
Definition at line 845 of file SSLIOP_Connector.cpp.
References base_connector_, and ACE_Connector< SVC_HANDLER, >::cancel().
00847 { 00848 TAO::SSLIOP::Connection_Handler* handler= 00849 dynamic_cast<TAO::SSLIOP::Connection_Handler*> (svc_handler); 00850 00851 if (handler) 00852 // Cancel from the connector 00853 return this->base_connector_.cancel (handler); 00854 00855 return -1; 00856 }
int TAO::SSLIOP::Connector::check_prefix | ( | const char * | endpoint | ) | [virtual] |
Definition at line 317 of file SSLIOP_Connector.cpp.
References ACE_OS::strchr(), ACE_OS::strlen(), and ACE_OS::strncmp().
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] |
Definition at line 75 of file SSLIOP_Connector.cpp.
References base_connector_, ACE_Strategy_Connector< SVC_HANDLER, >::close(), ACE_Strategy_Connector< SVC_HANDLER, >::concurrency_strategy(), and ACE_Strategy_Connector< SVC_HANDLER, >::creation_strategy().
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] |
Definition at line 85 of file SSLIOP_Connector.cpp.
References ACE_DEBUG, ACE_ERROR, ACE_TEXT(), TAO_Transport_Descriptor_Interface::endpoint(), TAO_Objref_Var_T< T >::in(), CORBA::is_nil(), LM_DEBUG, LM_ERROR, SSLIOP::SSL::port, qop_, Security::SecEstablishTrustPolicy, Security::SecQOPNoProtection, Security::SecQOPPolicy, TAO_SSLIOP_Endpoint::ssl_component(), ssliop_connect(), 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] |
Definition at line 264 of file SSLIOP_Connector.cpp.
References ACE_DEBUG, ACE_TEXT(), 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] |
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.
Definition at line 344 of file SSLIOP_Connector.cpp.
References CORBA::SystemException::_tao_minor_code(), ACE_BIT_DISABLED, CORBA::COMPLETED_NO, connect(), TAO_SSLIOP_Endpoint::iiop_endpoint(), Security::NoProtection, TAO_SSLIOP_Endpoint::ssl_component(), and TAO::VMCID.
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] |
Definition at line 219 of file SSLIOP_Connector.cpp.
References CORBA::SystemException::_tao_minor_code(), ACE_NEW_THROW_EX, CORBA::COMPLETED_NO, and TAO::VMCID.
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 CORBA::SystemException::_tao_minor_code(), ACE_NEW_THROW_EX, CORBA::COMPLETED_NO, and TAO::VMCID.
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] |
Definition at line 37 of file SSLIOP_Connector.cpp.
References ACE_NEW_RETURN, base_connector_, ACE_Strategy_Connector< SVC_HANDLER, >::open(), 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.
Definition at line 776 of file SSLIOP_Connector.cpp.
References TAO::SSLIOP::OwnCredentials::_narrow(), TAO::SSLIOP::OwnCredentials::_nil(), ACE_NEW_THROW_EX, TAO_Stub::get_policy(), TAO::SSLIOP::OpenSSL_st_var< T >::in(), TAO_Objref_Var_T< T >::in(), and CORBA::is_nil().
Referenced by ssliop_connect().
00778 { 00779 // Check if the user overrode the default invocation credentials. 00780 CORBA::Policy_var policy = 00781 stub->get_policy (::SecurityLevel3::ContextEstablishmentPolicyType); 00782 00783 SecurityLevel3::ContextEstablishmentPolicy_var creds_policy = 00784 SecurityLevel3::ContextEstablishmentPolicy::_narrow ( 00785 policy.in ()); 00786 00787 TAO::SSLIOP::OwnCredentials_var ssliop_credentials; 00788 00789 // Set the Credentials (X.509 certificates and corresponding private 00790 // keys) to be used for this invocation. 00791 if (!CORBA::is_nil (creds_policy.in ())) 00792 { 00793 SecurityLevel3::OwnCredentialsList_var creds_list = 00794 creds_policy->creds_list (); 00795 00796 if (creds_list->length () > 0) 00797 { 00798 // Assume that we've got an SSLIOP credential. 00799 SecurityLevel3::Credentials_ptr credentials = 00800 creds_list[0u]; 00801 00802 ssliop_credentials = 00803 TAO::SSLIOP::OwnCredentials::_narrow (credentials); 00804 00805 if (!CORBA::is_nil (ssliop_credentials.in ())) 00806 { 00807 TAO::SSLIOP::X509_var x509 = ssliop_credentials->x509 (); 00808 if (::SSL_use_certificate (ssl, x509.in ()) != 1) 00809 return TAO::SSLIOP::OwnCredentials::_nil (); 00810 00811 TAO::SSLIOP::EVP_PKEY_var evp = ssliop_credentials->evp (); 00812 if (evp.in () != 0 00813 && ::SSL_use_PrivateKey (ssl, evp.in ()) != 1) 00814 { 00815 // Invalidate the certificate we just set. 00816 (void) ::SSL_use_certificate (ssl, 0); 00817 return TAO::SSLIOP::OwnCredentials::_nil (); 00818 } 00819 } 00820 } 00821 } 00822 else 00823 { 00824 // Use the default certificate and private key, i.e. the one set 00825 // in the SSL_CTX that was used when creating the SSL data 00826 // structure. 00827 00828 /** 00829 * @todo Check if the CredentialsCurator contains a default set 00830 * of SSLIOP OwnCredentials. 00831 */ 00832 00833 TAO::SSLIOP::OwnCredentials_ptr & c = ssliop_credentials.out (); 00834 ACE_NEW_THROW_EX (c, 00835 TAO::SSLIOP::OwnCredentials ( 00836 ::SSL_get_certificate (ssl), 00837 ::SSL_get_privatekey (ssl)), 00838 CORBA::NO_MEMORY ()); 00839 } 00840 00841 return ssliop_credentials._retn (); 00842 }
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 CORBA::SystemException::_tao_minor_code(), ACE_BIT_DISABLED, ACE_BIT_ENABLED, ACE_DEBUG, ACE_ERROR, ACE_TEXT(), TAO_SSLIOP_Endpoint::addr_to_string(), AF_INET, base_connector_, TAO_Connection_Handler::cancel_pending_connection(), TAO::SSLIOP::Connection_Handler::close(), TAO_Transport::close_connection(), CORBA::COMPLETED_NO, ACE_Connector< SVC_HANDLER, >::connect(), TAO_Connection_Handler::connection_pending(), TAO_SSLIOP_Endpoint::credentials_set(), TAO_LF_CH_Event::error_detected(), 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(), LM_DEBUG, LM_ERROR, MAXHOSTNAMELEN, Security::NoProtection, TAO_SSLIOP_Endpoint::object_addr(), ACE_Svc_Handler<, >::peer(), TAO_Transport::purge_entry(), TAO_Wait_Strategy::register_handler(), ACE_Event_Handler_var::release(), ACE_Event_Handler::remove_reference(), retrieve_credentials(), Security::SecQOPIntegrity, Security::SecQOPNoProtection, TAO_SSLIOP_Endpoint::set_sec_attrs(), TAO_SSLIOP_Endpoint::ssl_component(), TAO_debug_level, TAO_Connection_Handler::transport(), TAO::VMCID, 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_DEBUG, 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_Event_Handler_var 00477 safe_handler (svc_handler); 00478 TAO::SSLIOP::OwnCredentials_var credentials = 00479 this->retrieve_credentials (resolver->stub (), 00480 svc_handler->peer ().ssl ()); 00481 00482 safe_handler.release (); 00483 00484 ssl_endpoint->set_sec_attrs (qop, trust, credentials.in()); 00485 } 00486 00487 // Check the Cache first for connections 00488 if (this->orb_core ()->lane_resources ().transport_cache ().find_transport ( 00489 desc, 00490 transport) == 0) 00491 { 00492 // ...eliminate svc_handle memory leak... 00493 // The make_svc_handler() method creates the service handler and 00494 // bumps the #REFCOUNT# up one extra. The extra reference count 00495 // in TAO_Connect_Creation_Strategy::make_svc_handler() is 00496 // needed in the case when connection completion is pending and 00497 // we are going to wait on a variable in the handler to changes, 00498 // signifying success or failure. Note, that this increment 00499 // cannot be done once the connect() returns since this might be 00500 // too late if another thread pick up the completion and 00501 // potentially deletes the handler before we get a chance to 00502 // increment the reference count. 00503 if (svc_handler) 00504 svc_handler->remove_reference(); 00505 00506 ACE_Event_Handler_var 00507 safe_handler (svc_handler); 00508 00509 if (TAO_debug_level > 2) 00510 ACE_DEBUG ((LM_DEBUG, 00511 ACE_TEXT ("TAO (%P|%t) - SSLIOP_Connector::ssliop_connect, ") 00512 ACE_TEXT ("got existing transport[%d]\n"), 00513 transport->id ())); 00514 00515 // When the transport is not connected wait for completion 00516 if (!transport->is_connected()) 00517 { 00518 if (!this->wait_for_connection_completion (resolver, 00519 transport, 00520 max_wait_time)) 00521 { 00522 ACE_ERROR ((LM_ERROR, 00523 ACE_TEXT ("TAO (%P|%t) - SSLIOP_Connector::ssliop_connect,") 00524 ACE_TEXT ("wait for completion failed\n"))); 00525 00526 } 00527 } 00528 } 00529 else 00530 { 00531 if (TAO_debug_level > 4) 00532 ACE_DEBUG ((LM_DEBUG, 00533 ACE_TEXT ("TAO (%P|%t) - SSLIOP_Connector::ssliop_connect, ") 00534 ACE_TEXT ("making a new connection \n"))); 00535 00536 // Purge connections (if necessary) 00537 this->orb_core ()->lane_resources ().transport_cache ().purge (); 00538 00539 // The svc_handler is created beforehand so that we can get 00540 // access to the underlying ACE_SSL_SOCK_Stream (the peer) and 00541 // its SSL pointer member prior to descending into the 00542 // ACE_Strategy_Connector (the "base_connector_"). This is 00543 // thread-safe and reentrant, hence no synchronization is 00544 // necessary. 00545 // 00546 // The make_svc_handler() method creates the service handler and 00547 // bumps the #REFCOUNT# up one extra. The extra reference count 00548 // in TAO_Connect_Creation_Strategy::make_svc_handler() is 00549 // needed in the case when connection completion is pending and 00550 // we are going to wait on a variable in the handler to changes, 00551 // signifying success or failure. Note, that this increment 00552 // cannot be done once the connect() returns since this might be 00553 // too late if another thread pick up the completion and 00554 // potentially deletes the handler before we get a chance to 00555 // increment the reference count. 00556 if (svc_handler == 0 && 00557 this->base_connector_.creation_strategy ()->make_svc_handler ( 00558 svc_handler) != 0) 00559 { 00560 if (TAO_debug_level > 0) 00561 ACE_DEBUG ((LM_ERROR, 00562 ACE_TEXT ("TAO (%P|%t) Unable to create SSLIOP ") 00563 ACE_TEXT ("service handler.\n"))); 00564 00565 return 0; 00566 } 00567 00568 ACE_Event_Handler_var 00569 safe_handler (svc_handler); 00570 00571 // Setup the establishment of trust connection properties, if 00572 // any. 00573 int verify_mode = 0; 00574 00575 // On the server side, "trust_in_client" requires that a peer 00576 // (client) certificate exist. Fail if one doesn't exist. 00577 // 00578 // In SSLIOP's case, trust_in_client also implies 00579 // trust_in_target. 00580 if (trust.trust_in_client) 00581 verify_mode = SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT; 00582 00583 // Require verification of the target's certificate. 00584 else if (trust.trust_in_target) 00585 verify_mode = SSL_VERIFY_PEER; 00586 00587 // Trust in neither the client nor the target is explicitly 00588 // specified. Use the default setting. 00589 else 00590 verify_mode = ACE_SSL_Context::instance ()->default_verify_mode (); 00591 00592 ::SSL_set_verify (svc_handler->peer ().ssl (), verify_mode, 0); 00593 00594 // The "eNULL" cipher disables encryption but still uses a 00595 // secure hash (e.g. SHA1 or MD5) to ensure integrity. (Try the 00596 // command "openssl ciphers -v eNULL".) 00597 // 00598 // Note that it is not possible to completely disable protection 00599 // here. 00600 if ((qop == ::Security::SecQOPNoProtection 00601 || qop == ::Security::SecQOPIntegrity) 00602 && ::SSL_set_cipher_list (svc_handler->peer ().ssl (), 00603 "eNULL") == 0) 00604 { 00605 if (TAO_debug_level > 0) 00606 ACE_DEBUG ((LM_ERROR, 00607 ACE_TEXT ("(%P|%t) Unable to set eNULL ") 00608 ACE_TEXT ("SSL cipher.\n"))); 00609 00610 throw CORBA::INV_POLICY (); 00611 } 00612 00613 // svc_handler is never reset..it still has the value 00614 (void)safe_handler.release (); 00615 00616 // Get the right synch options 00617 ACE_Synch_Options synch_options; 00618 00619 this->active_connect_strategy_->synch_options (max_wait_time, 00620 synch_options); 00621 00622 // The code used to set the timeout to zero, with the intent of 00623 // polling the reactor for connection completion. However, the side-effect 00624 // was to cause the connection to timeout immediately. 00625 00626 // We obtain the transport in the <svc_handler> variable. As we 00627 // know now that the connection is not available in Cache we can 00628 // make a new connection 00629 result = this->base_connector_.connect (svc_handler, 00630 remote_address, 00631 synch_options); 00632 00633 // base_connector_.connect() will increment the handler's 00634 // #REFCOUNT# once more. This is not required as we already hold 00635 // a reference to the handler, so we discard this second 00636 // reference. 00637 svc_handler->remove_reference (); 00638 00639 // There are three possibilities from calling connect(): (a) 00640 // connection succeeds immediately - in this case, the 00641 // #REFCOUNT# on the handler is two; (b) connection completion 00642 // is pending - in this case, the #REFCOUNT# on the handler is 00643 // also two; (c) connection fails immediately - in this case, 00644 // the #REFCOUNT# on the handler is one since close() gets 00645 // called on the handler. 00646 00647 // Make sure that we always do a remove_reference 00648 ACE_Event_Handler_var svc_handler_auto_ptr (svc_handler); 00649 00650 transport = 00651 svc_handler->transport (); 00652 00653 if (result == -1) 00654 { 00655 // No immediate result, wait for completion 00656 if (errno == EWOULDBLOCK) 00657 { 00658 // Try to wait until connection completion. Incase we block, then we 00659 // get a connected transport or not. In case of non block we get 00660 // a connected or not connected transport 00661 if (!this->wait_for_connection_completion (resolver, 00662 transport, 00663 max_wait_time)) 00664 { 00665 if (TAO_debug_level > 2) 00666 ACE_ERROR ((LM_ERROR, "TAO (%P|%t) - SSLIOP_Connector::" 00667 "ssliop_connect, " 00668 "wait for completion failed\n")); 00669 } 00670 } 00671 else 00672 { 00673 // Transport is not usable 00674 transport = 0; 00675 } 00676 } 00677 00678 // In case of errors transport is zero 00679 if (transport == 0) 00680 { 00681 // Give users a clue to the problem. 00682 if (TAO_debug_level) 00683 { 00684 char buffer [MAXHOSTNAMELEN + 6 + 1]; 00685 ssl_endpoint->addr_to_string (buffer, 00686 sizeof (buffer) - 1); 00687 ACE_DEBUG ((LM_ERROR, 00688 ACE_TEXT ("TAO (%P|%t) - SSL connection to ") 00689 ACE_TEXT ("<%s:%d> failed (%p)\n"), 00690 buffer, 00691 remote_address.get_port_number (), 00692 ACE_TEXT ("errno"))); 00693 } 00694 00695 return 0; 00696 } 00697 00698 // fix for bug 2654 00699 if (svc_handler->keep_waiting ()) 00700 { 00701 svc_handler->connection_pending (); 00702 } 00703 00704 // fix for bug 2654 00705 if (svc_handler->error_detected ()) 00706 { 00707 svc_handler->cancel_pending_connection (); 00708 } 00709 00710 // At this point, the connection has be successfully connected. 00711 // #REFCOUNT# is one. 00712 if (TAO_debug_level > 2) 00713 ACE_DEBUG ((LM_DEBUG, 00714 "TAO (%P|%t) - SSLIOP_Connector::ssliop_connect, " 00715 "new SSL connection to port %d on transport[%d]\n", 00716 remote_address.get_port_number (), 00717 svc_handler->peer ().get_handle ())); 00718 00719 // Add the handler to Cache 00720 int retval = 00721 this->orb_core ()-> 00722 lane_resources ().transport_cache ().cache_transport (desc, 00723 transport); 00724 00725 // Failure in adding to cache. 00726 if (retval != 0) 00727 { 00728 // Close the handler. 00729 svc_handler->close (); 00730 00731 if (TAO_debug_level > 0) 00732 { 00733 ACE_ERROR ((LM_ERROR, 00734 "TAO (%P|%t) - SLIIOP_Connector::ssliop_connect, " 00735 "could not add the new connection to cache\n")); 00736 } 00737 00738 return 0; 00739 } 00740 00741 // fix for bug 2654 00742 if (svc_handler->error_detected ()) 00743 { 00744 svc_handler->cancel_pending_connection (); 00745 transport->purge_entry(); 00746 return 0; 00747 } 00748 00749 if (transport->is_connected () && 00750 transport->wait_strategy ()->register_handler () != 0) 00751 { 00752 // Registration failures. 00753 00754 // Purge from the connection cache, if we are not in the cache, this 00755 // just does nothing. 00756 (void) transport->purge_entry (); 00757 00758 // Close the handler. 00759 (void) transport->close_connection (); 00760 00761 if (TAO_debug_level > 0) 00762 ACE_ERROR ((LM_ERROR, 00763 "TAO (%P|%t) - SSLIOP_Connector [%d]::ssliop_connect, " 00764 "could not register the transport " 00765 "in the reactor.\n", 00766 transport->id ())); 00767 00768 return 0; 00769 } 00770 } 00771 00772 return transport; 00773 }
The connector initiating connection requests for IIOP.
Definition at line 144 of file SSLIOP_Connector.h.
Referenced by cancel_svc_handler(), close(), open(), and ssliop_connect().
::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 138 of file SSLIOP_Connector.h.
Referenced by connect().