summaryrefslogtreecommitdiff
path: root/trunk/TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_Endpoint.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_Endpoint.cpp')
-rw-r--r--trunk/TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_Endpoint.cpp382
1 files changed, 382 insertions, 0 deletions
diff --git a/trunk/TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_Endpoint.cpp b/trunk/TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_Endpoint.cpp
new file mode 100644
index 00000000000..c2315dbca3c
--- /dev/null
+++ b/trunk/TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_Endpoint.cpp
@@ -0,0 +1,382 @@
+#include "orbsvcs/SSLIOP/SSLIOP_Endpoint.h"
+
+#include "tao/IIOP_Endpoint.h"
+
+#include "ace/OS_NS_stdio.h"
+#include "ace/OS_NS_string.h"
+#include "ace/os_include/os_netdb.h"
+
+#include "tao/debug.h"
+
+ACE_RCSID (SSLIOP,
+ SSLIOP_Endpoint,
+ "$Id$")
+
+
+#if !defined (__ACE_INLINE__)
+# include "orbsvcs/SSLIOP/SSLIOP_Endpoint.inl"
+#endif /* __ACE_INLINE__ */
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+TAO_SSLIOP_Endpoint::TAO_SSLIOP_Endpoint (const ::SSLIOP::SSL *ssl_component,
+ TAO_IIOP_Endpoint *iiop_endp)
+ : TAO_Endpoint (IOP::TAG_INTERNET_IOP),
+ object_addr_ (),
+ next_ (0),
+ iiop_endpoint_ (iiop_endp),
+ destroy_iiop_endpoint_ (false),
+ qop_ (::Security::SecQOPIntegrityAndConfidentiality),
+#if !defined (VXWORKS) && !defined (__QNX__)
+ // Some compilers don't like the initialization
+ trust_ (),
+#endif /* !VXWORKS && !__QNX__ */
+ credentials_ (),
+ credentials_set_ (0)
+{
+ if (ssl_component != 0)
+ {
+ // Copy the security association options in the IOR's SSL tagged
+ // component.
+ this->ssl_component_.target_supports = ssl_component->target_supports;
+ this->ssl_component_.target_requires = ssl_component->target_requires;
+ this->ssl_component_.port = ssl_component->port;
+ }
+ else
+ {
+ // No SSL tagged component is available so construct a default
+ // set of security association options, in addition to the IANA
+ // assigned IIOP over SSL port (684). This is generally a
+ // client side issue.
+
+ // Clear all bits in the SSLIOP::SSL association option fields.
+ this->ssl_component_.target_supports = 0;
+ this->ssl_component_.target_requires = 0;
+
+ // SSLIOP requires these Security::AssociationOptions by default.
+ ACE_SET_BITS (this->ssl_component_.target_requires,
+ ::Security::Integrity
+ | ::Security::Confidentiality
+ | ::Security::NoDelegation);
+
+ // SSLIOP supports these Security::AssociationOptions by
+ // default.
+ //
+ // Note that the Security::NoProtection bit is set since we
+ // can't be sure if the server supports SSL, and TAO's SSLIOP
+ // implementation must support IIOP over SSL and plain IIOP.
+ ACE_SET_BITS (this->ssl_component_.target_supports,
+ ::Security::Integrity
+ | ::Security::Confidentiality
+ | ::Security::EstablishTrustInTarget
+ | ::Security::NoProtection
+ | ::Security::NoDelegation);
+
+ // Initialize the default SSL port to zero, not the IANA
+ // assigned IIOP over SSL port (684). We usually only get here
+ // if we're creating a profile on the client side using an IOR
+ // that does not contain an SSLIOP tagged component.
+ this->ssl_component_.port = 0;
+ }
+
+ // Invalidate the Addr until the first attempt to use it is made.
+ this->object_addr_.set_type (-1);
+
+ this->trust_.trust_in_target = 1;
+ this->trust_.trust_in_client = 1;
+}
+
+TAO_SSLIOP_Endpoint::~TAO_SSLIOP_Endpoint (void)
+{
+ if (this->destroy_iiop_endpoint_)
+ delete this->iiop_endpoint_;
+}
+
+#if 0
+static void
+dump_endpoint (const char* msg, const TAO_Endpoint *other_endpoint)
+{
+
+ TAO_Endpoint *endpt = const_cast<TAO_Endpoint *> (other_endpoint);
+
+ TAO_SSLIOP_Endpoint *endpoint =
+ dynamic_cast<TAO_SSLIOP_Endpoint *> (endpt);
+
+ if (endpoint == 0)
+ {
+ ACE_DEBUG ((LM_DEBUG, "TAO (%P|%t) endpoint - %s: Unable to cast an endpoint to SSLIOP_Endpoint\n", msg));
+ return;
+ }
+
+ char hostaddr[MAXHOSTNAMELEN + 16];
+ int gothost = endpoint->addr_to_string (hostaddr, sizeof hostaddr);
+
+ ACE_DEBUG ((LM_INFO, "TAO (%P|%t) SSLIOPEndpoint %s - %@ {%s, ssl=%d, iiop=%d,"
+ " qop=%d, trst=(%d,%d), c=%@, crdh=0x%x}, h=0x%x\n",
+ msg,
+ endpoint,
+ (gothost == 0 ? hostaddr : "*UNKNOWN*"),
+ endpoint->ssl_component ().port ,
+ endpoint->iiop_endpoint ()->port (),
+ endpoint->qop() ,
+ endpoint->trust().trust_in_target ,
+ endpoint->trust().trust_in_client ,
+ endpoint->credentials() ,
+ (endpoint->credentials_set () ? endpoint->credentials()->hash () : 0) ,
+ endpoint->hash ()));
+}
+#endif /* 0 */
+
+int
+TAO_SSLIOP_Endpoint::addr_to_string (char *buffer, size_t length)
+{
+ size_t actual_len =
+ ACE_OS::strlen (this->iiop_endpoint_->host ()) // chars in host name
+ + sizeof (':') // delimiter
+ + ACE_OS::strlen ("65536") // max port
+ + sizeof ('\0');
+
+ if (length < actual_len)
+ return -1;
+
+ ACE_OS::sprintf (buffer,
+ "%s:%d",
+ this->iiop_endpoint_->host (),
+ this->ssl_component_.port);
+
+ return 0;
+}
+
+
+TAO_Endpoint *
+TAO_SSLIOP_Endpoint::next (void)
+{
+ return this->next_;
+}
+
+CORBA::Boolean
+TAO_SSLIOP_Endpoint::is_equivalent (const TAO_Endpoint *other_endpoint)
+{
+ TAO_Endpoint *endpt = const_cast<TAO_Endpoint *> (other_endpoint);
+
+ TAO_SSLIOP_Endpoint *endpoint =
+ dynamic_cast<TAO_SSLIOP_Endpoint *> (endpt);
+
+ if (endpoint == 0)
+ return 0;
+
+ ::Security::EstablishTrust t = endpoint->trust ();
+
+ if ((this->ssl_component_.port != 0
+ && endpoint->ssl_component_.port != 0
+ && this->ssl_component_.port != endpoint->ssl_component_.port)
+ || this->qop_ != endpoint->qop ()
+ || this->trust_.trust_in_target != t.trust_in_target
+ || this->trust_.trust_in_client != t.trust_in_client
+ || (!CORBA::is_nil (this->credentials_.in ())
+ && !(*this->credentials_.in () == *endpoint->credentials ())))
+ {
+ return 0;
+ }
+
+ // Comparing the underlying iiop endpoints is wrong, as their port
+ // numbers often may not make sense. Or may not being used anyway.
+ // Therefore, we only need to directly compare the hosts. See also the
+ // comments in the hash() method.
+ if (this->iiop_endpoint() == 0 || endpoint->iiop_endpoint() == 0)
+ return 0;
+
+ if ((ACE_OS::strcmp (this->iiop_endpoint()->host (),
+ endpoint->iiop_endpoint()->host ()) != 0))
+ return 0;
+
+ return 1;
+}
+
+TAO_Endpoint *
+TAO_SSLIOP_Endpoint::duplicate (void)
+{
+ TAO_SSLIOP_Endpoint *endpoint = 0;
+
+ // @@ We need to set the priority of the newly formed endpoint. It
+ // shouldnt be a problem as long as SSL is not used with RTCORBA.
+ ACE_NEW_RETURN (endpoint,
+ TAO_SSLIOP_Endpoint (&this->ssl_component_,
+ 0),
+ 0);
+
+ if (this->credentials_set_)
+ endpoint->set_sec_attrs (this->qop_,this->trust_, this->credentials_.in());
+
+ endpoint->iiop_endpoint (this->iiop_endpoint_, true);
+ endpoint->hash_val_ = this->hash_val_;
+ return endpoint;
+}
+
+CORBA::ULong
+TAO_SSLIOP_Endpoint::hash (void)
+{
+ // there is actually the potential for a race of the inverse case,
+ // since setting the security attributes will reset the hash_val_,
+ // it is possible this test to pass, but then have the hash reset
+ // before the value is returned.
+ if (this->hash_val_ != 0)
+ return this->hash_val_;
+
+ // Do this with no locks held, as it may try to acquire it, too.
+ const ACE_INET_Addr &oaddr = this->object_addr();
+
+ { // nested scope for the lock
+ ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
+ guard,
+ this->addr_lookup_lock_,
+ this->hash_val_);
+ // .. DCL
+ if (this->hash_val_ != 0)
+ return this->hash_val_;
+
+
+ // Note that we are not using the underlying IIOP endpoint's hash
+ // value in order to avoid the influence of the IIOP port number,
+ // since it is ignored anyway. When it features a
+ // purely fictional port number, as when accepting an SSL
+ // connection, the unsecured port is undefined and
+ // had we used it in computing the hash it would have broken the
+ // bi-directional support - as the 'guessed' IIOP port value will
+ // hardly match the one specified in the bi-dir service context.
+ this->hash_val_ =
+ oaddr.get_ip_address ()
+ + this->ssl_component_.port;
+ }
+
+ return this->hash_val_;
+}
+
+
+const ACE_INET_Addr &
+TAO_SSLIOP_Endpoint::object_addr (void) const
+{
+ // The object_addr_ is initialized here, rather than at IOR decode
+ // time for several reasons:
+ // 1. A request on the object may never be invoked.
+ // 2. The DNS setup may have changed dynamically.
+ // ...etc..
+
+ // Double checked locking optimization.
+ if (this->object_addr_.get_type () != AF_INET)
+ {
+ const ACE_INET_Addr &iiop_addr = this->iiop_endpoint_->object_addr ();
+
+ ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
+ guard,
+ this->addr_lookup_lock_,
+ this->object_addr_);
+
+ if (this->object_addr_.get_type () != AF_INET)
+ {
+ this->object_addr_ = iiop_addr;
+ this->object_addr_.set_port_number (this->ssl_component_.port);
+ }
+ }
+
+ return this->object_addr_;
+}
+
+void
+TAO_SSLIOP_Endpoint::set_sec_attrs (::Security::QOP q,
+ const ::Security::EstablishTrust &t,
+ const TAO::SSLIOP::OwnCredentials_ptr c)
+{
+ if (this->credentials_set_)
+ return;
+
+ ACE_GUARD (TAO_SYNCH_MUTEX,
+ guard,
+ this->addr_lookup_lock_);
+
+ // double-check
+ if (this->credentials_set_)
+ return;
+
+ this->qop_ = q;
+ this->trust_ = t;
+ this->credentials_ = TAO::SSLIOP::OwnCredentials::_duplicate (c);
+ this->credentials_set_ = 1;
+
+ // reset the hash value to force a recomputation.
+ this->hash_val_ = 0;
+}
+
+
+
+
+TAO_SSLIOP_Synthetic_Endpoint::~TAO_SSLIOP_Synthetic_Endpoint ()
+{
+}
+
+TAO_SSLIOP_Synthetic_Endpoint::TAO_SSLIOP_Synthetic_Endpoint (const ::SSLIOP::SSL *ssl)
+ : TAO_SSLIOP_Endpoint (ssl, 0)
+{
+}
+
+
+TAO_SSLIOP_Synthetic_Endpoint::TAO_SSLIOP_Synthetic_Endpoint (TAO_IIOP_Endpoint *iiop_endp)
+ : TAO_SSLIOP_Endpoint ((const ::SSLIOP::SSL *)0, iiop_endp)
+{
+ this->ssl_component_.port = iiop_endp->port ();
+}
+
+
+CORBA::Boolean
+TAO_SSLIOP_Synthetic_Endpoint::is_equivalent (const TAO_Endpoint *other_endpoint)
+{
+ TAO_Endpoint *endpt = const_cast<TAO_Endpoint *> (other_endpoint);
+
+ TAO_SSLIOP_Endpoint *endpoint =
+ dynamic_cast<TAO_SSLIOP_Endpoint *> (endpt);
+
+ if (endpoint == 0)
+ return 0;
+
+ if ((this->ssl_component ().port != 0
+ && endpoint->ssl_component ().port != 0
+ && this->ssl_component ().port != endpoint->ssl_component ().port)
+ || this->qop () < endpoint->qop ())
+ {
+ return 0;
+ }
+
+ // Comparing the underlying iiop endpoints is wrong, as their port
+ // numbers often may not make sense, or are not being used anyway.
+ // Therefore, directly comparing the hosts at this point. See also the
+ // comments in the hash() method
+ if (this->iiop_endpoint() == 0 || endpoint->iiop_endpoint() == 0)
+ return 0;
+
+ if ((ACE_OS::strcmp (this->iiop_endpoint()->host (),
+ endpoint->iiop_endpoint()->host ()) != 0))
+ return 0;
+
+ return 1;
+}
+
+TAO_Endpoint *
+TAO_SSLIOP_Synthetic_Endpoint::duplicate (void)
+{
+ TAO_SSLIOP_Synthetic_Endpoint *endpoint = 0;
+
+ // @@ We need to set the priority of the newly formed endpoint. It
+ // shouldnt be a problem as long as SSL is not used with RTCORBA.
+ ACE_NEW_RETURN (endpoint,
+ TAO_SSLIOP_Synthetic_Endpoint (&(this->ssl_component ())),
+ 0);
+
+ if (this->credentials_set())
+ endpoint->set_sec_attrs (this->qop (),this->trust (), this->credentials ());
+
+ endpoint->iiop_endpoint (this->iiop_endpoint (), true);
+ endpoint->hash_val_ = this->hash ();
+ return endpoint;
+}
+
+TAO_END_VERSIONED_NAMESPACE_DECL