#include <SSLIOP_Connector.h>
Inheritance diagram for TAO::SSLIOP::Connector:
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.
|
Reimplemented from TAO::IIOP_SSL_Connector. Definition at line 134 of file SSLIOP_Connector.h. |
|
Reimplemented from TAO::IIOP_SSL_Connector. Definition at line 123 of file SSLIOP_Connector.h. |
|
Reimplemented from TAO::IIOP_SSL_Connector. Definition at line 126 of file SSLIOP_Connector.h. |
|
Reimplemented from TAO::IIOP_SSL_Connector. Definition at line 130 of file SSLIOP_Connector.h. |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
IIOP-specific connection establishment.
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 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 } |
|
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 } |
|
The connector initiating connection requests for IIOP.
Reimplemented from TAO::IIOP_SSL_Connector. Definition at line 146 of file SSLIOP_Connector.h. |
|
Our connect strategy.
Reimplemented from TAO::IIOP_SSL_Connector. Definition at line 143 of file SSLIOP_Connector.h. |
|
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. |