📄 ssliop_connector.cpp
字号:
#include "SSLIOP_Connector.h"
#include "SSLIOP_Credentials.h"
#include "SSLIOP_Profile.h"
#include "SSLIOP_Util.h"
#include "SSLIOP_X509.h"
#include "tao/debug.h"
#include "tao/ORB_Core.h"
#include "tao/Client_Strategy_Factory.h"
#include "tao/Environment.h"
#include "tao/Base_Transport_Property.h"
#include "tao/Transport_Cache_Manager.h"
#include "tao/Thread_Lane_Resources.h"
#include "tao/Stub.h"
#include "tao/Transport_Connector.h"
#include "tao/Blocked_Connect_Strategy.h"
#include "tao/Wait_Strategy.h"
#include "tao/Profile_Transport_Resolver.h"
#include "ace/Auto_Ptr.h"
#include "ace/os_include/os_netdb.h"
ACE_RCSID (TAO_SSLIOP,
SSLIOP_Connector,
"SSLIOP_Connector.cpp,v 1.82 2003/11/24 02:46:02 bala Exp")
#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
template class TAO_Connect_Concurrency_Strategy<TAO_SSLIOP_Connection_Handler>;
template class TAO_Connect_Creation_Strategy<TAO_SSLIOP_Connection_Handler>;
template class ACE_Strategy_Connector<TAO_SSLIOP_Connection_Handler, ACE_SSL_SOCK_CONNECTOR>;
template class ACE_Connect_Strategy<TAO_SSLIOP_Connection_Handler, ACE_SSL_SOCK_CONNECTOR>;
template class ACE_Connector_Base<TAO_SSLIOP_Connection_Handler>;
template class ACE_Connector<TAO_SSLIOP_Connection_Handler, ACE_SSL_SOCK_CONNECTOR>;
template class ACE_NonBlocking_Connect_Handler<TAO_SSLIOP_Connection_Handler>;
template class ACE_Auto_Basic_Ptr<TAO_SSLIOP_Connection_Handler>;
#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
#pragma instantiate TAO_Connect_Concurrency_Strategy<TAO_SSLIOP_Connection_Handler>
#pragma instantiate TAO_Connect_Creation_Strategy<TAO_SSLIOP_Connection_Handler>
#pragma instantiate ACE_Strategy_Connector<TAO_SSLIOP_Connection_Handler, ACE_SSL_SOCK_CONNECTOR>
#pragma instantiate ACE_Connect_Strategy<TAO_SSLIOP_Connection_Handler, ACE_SSL_SOCK_CONNECTOR>
#pragma instantiate ACE_Connector_Base<TAO_SSLIOP_Connection_Handler>
#pragma instantiate ACE_Connector<TAO_SSLIOP_Connection_Handler, ACE_SSL_SOCK_CONNECTOR>
#pragma instantiate ACE_NonBlocking_Connect_Handler<TAO_SSLIOP_Connection_Handler>
#pragma instantiate ACE_Auto_Basic_Ptr<TAO_SSLIOP_Connection_Handler>
#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */
TAO_SSLIOP_Connector::TAO_SSLIOP_Connector (Security::QOP qop)
: TAO_IIOP_SSL_Connector (),
qop_ (qop),
connect_strategy_ (),
base_connector_ (),
handler_state_ ()
{
}
int
TAO_SSLIOP_Connector::open (TAO_ORB_Core *orb_core)
{
// Since the ACE_Strategy_Connector (and ACE_Connector) cannot
// handle non-blocking connections with protocols that have more
// than once handshake, such as SSL, force blocking connections for
// SSLIOP. This deficiency will be addressed soon.
ACE_NEW_RETURN (this->active_connect_strategy_,
TAO_Blocked_Connect_Strategy (orb_core),
-1);
if (this->TAO_IIOP_SSL_Connector::open (orb_core) == -1)
return -1;
if (TAO_SSLIOP_Util::setup_handler_state (orb_core,
&(this->tcp_properties_),
this->handler_state_) != 0)
return -1;
// Our connect creation strategy
TAO_SSLIOP_CONNECT_CREATION_STRATEGY *connect_creation_strategy = 0;
ACE_NEW_RETURN (connect_creation_strategy,
TAO_SSLIOP_CONNECT_CREATION_STRATEGY
(orb_core->thr_mgr (),
orb_core,
&(this->handler_state_),
0 /* Forcibly disable TAO's GIOPlite feature.
It introduces a security hole. */),
-1);
// Our activation strategy
TAO_SSLIOP_CONNECT_CONCURRENCY_STRATEGY *concurrency_strategy = 0;
ACE_NEW_RETURN (concurrency_strategy,
TAO_SSLIOP_CONNECT_CONCURRENCY_STRATEGY (orb_core),
-1);
ACE_Reactor *r = this->orb_core ()->reactor ();
return this->base_connector_.open (r,
connect_creation_strategy,
&this->connect_strategy_,
concurrency_strategy);
}
int
TAO_SSLIOP_Connector::close (void)
{
(void) this->TAO_IIOP_SSL_Connector::close ();
delete this->base_connector_.creation_strategy ();
delete this->base_connector_.concurrency_strategy ();
return this->base_connector_.close ();
}
TAO_Transport *
TAO_SSLIOP_Connector::connect (TAO::Profile_Transport_Resolver *resolver,
TAO_Transport_Descriptor_Interface *desc,
ACE_Time_Value *timeout
ACE_ENV_ARG_DECL)
{
if (TAO_debug_level > 0)
ACE_DEBUG ((LM_DEBUG,
ACE_TEXT ("TAO (%P|%t) Connector::connect - ")
ACE_TEXT ("looking for SSLIOP connection.\n")));
TAO_Endpoint *endpoint = desc->endpoint ();
if (endpoint->tag () != IOP::TAG_INTERNET_IOP)
return 0;
TAO_SSLIOP_Endpoint *ssl_endpoint =
ACE_dynamic_cast (TAO_SSLIOP_Endpoint *,
endpoint);
if (ssl_endpoint == 0)
return 0;
// @@ TODO: The EstablishTrust policy should be evaluated once per
// connection, not once per invocation. This should
// improve performance.
//
// Check if the user overrode the default establishment of trust
// policy for the current object.
CORBA::Policy_var policy =
resolver->stub ()->get_policy (Security::SecEstablishTrustPolicy
ACE_ENV_ARG_PARAMETER);
ACE_CHECK_RETURN (0);
SecurityLevel2::EstablishTrustPolicy_var trust_policy =
SecurityLevel2::EstablishTrustPolicy::_narrow (policy.in ()
ACE_ENV_ARG_PARAMETER);
ACE_CHECK_RETURN (0);
// We use a pointer and temporary to make it obvious to determine
// if no establishment of trust policy was set. Specifically, if
// the "trust" pointer below is zero, then the SSLIOP pluggable
// protocol default value will be used.
Security::EstablishTrust trust = { 0 , 0 };
if (!CORBA::is_nil (trust_policy.in ()))
{
trust = trust_policy->trust (ACE_ENV_SINGLE_ARG_PARAMETER);
ACE_CHECK_RETURN (0);
}
// Flag that states whether any form of establishment of trust
// should occur.
CORBA::Boolean establish_trust =
trust.trust_in_target || trust.trust_in_client;
// @@ Should this be in a "policy validator?"
//
// If the SSL port is zero, then no SSLIOP tagged component was
// available in the IOR, meaning that there is no way to establish
// trust. Throw an exception.
if (ssl_endpoint->ssl_component ().port == 0
&& establish_trust)
{
if (TAO_debug_level > 0)
{
ACE_ERROR ((LM_ERROR,
ACE_TEXT ("TAO_SSLIOP (%P|%t) ERROR: ")
ACE_TEXT ("Cannot establish trust since ")
ACE_TEXT ("no SSLIOP tagged component was ")
ACE_TEXT ("found in the IOR.\n")));
}
ACE_THROW_RETURN (CORBA::INV_POLICY (), // @@ Correct exception?
0);
}
// Check if the user overrode the default Quality-of-Protection for
// the current object.
policy = resolver->stub ()->get_policy (Security::SecQOPPolicy
ACE_ENV_ARG_PARAMETER);
ACE_CHECK_RETURN (0);
SecurityLevel2::QOPPolicy_var qop_policy =
SecurityLevel2::QOPPolicy::_narrow (policy.in ()
ACE_ENV_ARG_PARAMETER);
ACE_CHECK_RETURN (0);
// Temporary variable used to avoid overwriting the default value
// set when the ORB was initialized.
Security::QOP qop = this->qop_;
if (!CORBA::is_nil (qop_policy.in ()))
{
qop = qop_policy->qop (ACE_ENV_SINGLE_ARG_PARAMETER);
ACE_CHECK_RETURN (0);
}
// If the SSL port is zero, then no SSLIOP tagged component was
// available in the IOR, meaning that there is no way to make a
// secure invocation. Throw an exception.
if (qop != Security::SecQOPNoProtection
&& ssl_endpoint->ssl_component ().port == 0)
{
if (TAO_debug_level > 0)
{
ACE_ERROR ((LM_ERROR,
ACE_TEXT ("TAO_SSLIOP (%P|%t) ERROR: ")
ACE_TEXT ("Cannot make secure invocation since ")
ACE_TEXT ("no SSLIOP tagged component was ")
ACE_TEXT ("found in the IOR.\n")));
}
ACE_THROW_RETURN (CORBA::INV_POLICY (), // @@ Correct exception?
0);
}
if ((!establish_trust && qop == Security::SecQOPNoProtection)
|| ssl_endpoint->ssl_component ().port == 0)
{
return this->iiop_connect (ssl_endpoint,
resolver,
timeout
ACE_ENV_ARG_PARAMETER);
}
return this->ssliop_connect (ssl_endpoint,
qop,
trust,
resolver,
desc,
timeout
ACE_ENV_ARG_PARAMETER);
}
TAO_Profile *
TAO_SSLIOP_Connector::create_profile (TAO_InputCDR& cdr)
{
TAO_Profile *pfile;
ACE_NEW_RETURN (pfile,
TAO_SSLIOP_Profile (this->orb_core ()),
0);
int r = pfile->decode (cdr);
if (r == -1)
{
pfile->_decr_refcnt ();
pfile = 0;
}
return pfile;
}
TAO_Profile *
TAO_SSLIOP_Connector::make_profile (ACE_ENV_SINGLE_ARG_DECL)
{
// The endpoint should be of the form:
// N.n@host:port/object_key
// or:
// host:port/object_key
TAO_Profile *profile = 0;
ACE_NEW_THROW_EX (profile,
TAO_SSLIOP_Profile (this->orb_core (),
0), // SSL component
CORBA::NO_MEMORY (
CORBA::SystemException::_tao_minor_code (
TAO_DEFAULT_MINOR_CODE,
ENOMEM),
CORBA::COMPLETED_NO));
ACE_CHECK_RETURN (0);
return profile;
}
TAO_Transport*
TAO_SSLIOP_Connector::iiop_connect (TAO_SSLIOP_Endpoint *ssl_endpoint,
TAO::Profile_Transport_Resolver *resolver,
ACE_Time_Value *timeout
ACE_ENV_ARG_DECL)
{
const SSLIOP::SSL &ssl_component = ssl_endpoint->ssl_component ();
// Only allow connection to the insecure IIOP port if the endpoint
// explicitly allows it, i.e. if the Security::NoProtection security
// association bit is set in the SSLIOP::SSL::target_supports field.
// The server performs the same permission check, so this check is
// an optimization since a connection will not be established
// needlessly, i.e. rejected due to lack of permission.
//
// Note that it is still possible for the standard non-SSLIOP aware
// IIOP pluggable protocol to attempt to connect to the insecure
// port. In that case, the server will have to prevent the
// connection, and subsequently the request, from completing.
if (ACE_BIT_DISABLED (ssl_component.target_supports,
Security::NoProtection))
ACE_THROW_RETURN (CORBA::NO_PERMISSION (
CORBA::SystemException::_tao_minor_code (
TAO_DEFAULT_MINOR_CODE,
EPERM),
CORBA::COMPLETED_NO),
0);
TAO_IIOP_Endpoint *iiop_endpoint = ssl_endpoint->iiop_endpoint ();
// An IIOP-only transport descriptor must be used instead of the one
// passed to this method since the latter is used for SSLIOP
// connections. Doing so prevents an IIOP-only cached transport
// from being associated with an SSLIOP connection.
TAO_Base_Transport_Property iiop_desc (iiop_endpoint);
// Note that the IIOP-only transport descriptor is used!
return this->TAO_IIOP_SSL_Connector::connect (resolver,
&iiop_desc,
timeout
ACE_ENV_ARG_PARAMETER);
}
TAO_Transport *
TAO_SSLIOP_Connector::ssliop_connect (TAO_SSLIOP_Endpoint *ssl_endpoint,
Security::QOP qop,
const Security::EstablishTrust &trust,
TAO::Profile_Transport_Resolver *resolver,
TAO_Transport_Descriptor_Interface *desc,
ACE_Time_Value *max_wait_time
ACE_ENV_ARG_DECL)
{
const SSLIOP::SSL &ssl_component = ssl_endpoint->ssl_component ();
// @@ The following check for "required insecurity" seems odd, but
// I haven't seen anything in the Security spec that says this
// policy isn't possible.
// -Ossama
// If the endpoint requires an insecure connection, i.e. the
// Security::NoProtection security association bit in the
// SSLIOP::SSL::target_requires field is enabled, then prevent an
// SSL connection from occuring.
if (ACE_BIT_ENABLED (ssl_component.target_requires,
Security::NoProtection))
ACE_THROW_RETURN (CORBA::NO_PERMISSION (
CORBA::SystemException::_tao_minor_code (
TAO_DEFAULT_MINOR_CODE,
EPERM),
CORBA::COMPLETED_NO),
0);
// If the invocation wants integrity without confidentiality but the
// server does not support "no protection," then it won't be
// possible provide integrity. In order to support integrity
// without confidentiality, encryption must be disabled but secure
// hashes must remain enabled. This is achieved using the "eNULL"
// cipher. However, the "eNULL" cipher is only enabled on the
// server side if "no protection" is enabled.
if (ACE_BIT_DISABLED (ssl_component.target_supports,
Security::NoProtection)
&& qop == Security::SecQOPIntegrity)
ACE_THROW_RETURN (CORBA::INV_POLICY (), 0);
const ACE_INET_Addr &remote_address =
ssl_endpoint->object_addr ();
// Verify that the remote ACE_INET_Addr was initialized
// properly. Failure can occur if hostname lookup failed when
// initializing the remote ACE_INET_Addr.
if (remote_address.get_type () != AF_INET)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -