SSLIOP_Endpoint.cpp

Go to the documentation of this file.
00001 #include "orbsvcs/SSLIOP/SSLIOP_Endpoint.h"
00002 
00003 #include "tao/IIOP_Endpoint.h"
00004 
00005 #include "ace/OS_NS_stdio.h"
00006 #include "ace/OS_NS_string.h"
00007 #include "ace/os_include/os_netdb.h"
00008 
00009 #include "tao/debug.h"
00010 
00011 ACE_RCSID (SSLIOP,
00012            SSLIOP_Endpoint,
00013            "SSLIOP_Endpoint.cpp,v 1.27 2006/03/14 06:14:35 jtc Exp")
00014 
00015 
00016 #if !defined (__ACE_INLINE__)
00017 # include "orbsvcs/SSLIOP/SSLIOP_Endpoint.i"
00018 #endif /* __ACE_INLINE__ */
00019 
00020 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00021 
00022 TAO_SSLIOP_Endpoint::TAO_SSLIOP_Endpoint (const ::SSLIOP::SSL *ssl_component,
00023                                           TAO_IIOP_Endpoint *iiop_endp)
00024   : TAO_Endpoint (IOP::TAG_INTERNET_IOP),
00025     object_addr_ (),
00026     next_ (0),
00027     iiop_endpoint_ (iiop_endp),
00028     destroy_iiop_endpoint_ (false),
00029     qop_ (::Security::SecQOPIntegrityAndConfidentiality),
00030 #if !defined (VXWORKS) && !defined (__QNX__)
00031     // Some compilers don't like the initialization
00032     trust_ (),
00033 #endif /* !VXWORKS && !__QNX__ */
00034     credentials_ (),
00035     credentials_set_ (0)
00036 {
00037   if (ssl_component != 0)
00038     {
00039       // Copy the security association options in the IOR's SSL tagged
00040       // component.
00041       this->ssl_component_.target_supports = ssl_component->target_supports;
00042       this->ssl_component_.target_requires = ssl_component->target_requires;
00043       this->ssl_component_.port = ssl_component->port;
00044     }
00045   else
00046     {
00047       // No SSL tagged component is available so construct a default
00048       // set of security association options, in addition to the IANA
00049       // assigned IIOP over SSL port (684).  This is generally a
00050       // client side issue.
00051 
00052       // Clear all bits in the SSLIOP::SSL association option fields.
00053       this->ssl_component_.target_supports = 0;
00054       this->ssl_component_.target_requires = 0;
00055 
00056       // SSLIOP requires these Security::AssociationOptions by default.
00057       ACE_SET_BITS (this->ssl_component_.target_requires,
00058                     ::Security::Integrity
00059                     | ::Security::Confidentiality
00060                     | ::Security::NoDelegation);
00061 
00062       // SSLIOP supports these Security::AssociationOptions by
00063       // default.
00064       //
00065       // Note that the Security::NoProtection bit is set since we
00066       // can't be sure if the server supports SSL, and TAO's SSLIOP
00067       // implementation must support IIOP over SSL and plain IIOP.
00068       ACE_SET_BITS (this->ssl_component_.target_supports,
00069                     ::Security::Integrity
00070                     | ::Security::Confidentiality
00071                     | ::Security::EstablishTrustInTarget
00072                     | ::Security::NoProtection
00073                     | ::Security::NoDelegation);
00074 
00075       // Initialize the default SSL port to zero, not the IANA
00076       // assigned IIOP over SSL port (684).  We usually only get here
00077       // if we're creating a profile on the client side using an IOR
00078       // that does not contain an SSLIOP tagged component.
00079       this->ssl_component_.port = 0;
00080     }
00081 
00082   // Invalidate the Addr until the first attempt to use it is made.
00083   this->object_addr_.set_type (-1);
00084 
00085   this->trust_.trust_in_target = 1;
00086   this->trust_.trust_in_client = 1;
00087 }
00088 
00089 TAO_SSLIOP_Endpoint::~TAO_SSLIOP_Endpoint (void)
00090 {
00091   if (this->destroy_iiop_endpoint_)
00092     delete this->iiop_endpoint_;
00093 }
00094 
00095 #if 0
00096 static void
00097 dump_endpoint (const char* msg, const TAO_Endpoint *other_endpoint)
00098 {
00099   
00100   TAO_Endpoint *endpt = const_cast<TAO_Endpoint *> (other_endpoint);
00101 
00102   TAO_SSLIOP_Endpoint *endpoint =
00103     dynamic_cast<TAO_SSLIOP_Endpoint *> (endpt);
00104 
00105   if (endpoint == 0)
00106   {
00107     ACE_DEBUG ((LM_DEBUG, "TAO (%P|%t) endpoint - %s: Unable to cast an endpoint to SSLIOP_Endpoint\n", msg));
00108     return;
00109   }
00110   
00111   char hostaddr[MAXHOSTNAMELEN + 16];
00112   int gothost = endpoint->addr_to_string (hostaddr, sizeof hostaddr);
00113 
00114   ACE_DEBUG ((LM_INFO, "TAO (%P|%t) SSLIOPEndpoint %s - %@ {%s, ssl=%d, iiop=%d,"
00115                 " qop=%d, trst=(%d,%d), c=%@, crdh=0x%x}, h=0x%x\n", 
00116                 msg,
00117                 endpoint,
00118                 (gothost == 0 ? hostaddr : "*UNKNOWN*"),
00119                 endpoint->ssl_component ().port , 
00120                 endpoint->iiop_endpoint ()->port (),
00121                 endpoint->qop() , 
00122                 endpoint->trust().trust_in_target , 
00123                 endpoint->trust().trust_in_client ,
00124                 endpoint->credentials() , 
00125                 (endpoint->credentials_set () ? endpoint->credentials()->hash () : 0) , 
00126                 endpoint->hash ()));
00127 }
00128 #endif /* 0 */
00129 
00130 int
00131 TAO_SSLIOP_Endpoint::addr_to_string (char *buffer, size_t length)
00132 {
00133   size_t actual_len =
00134     ACE_OS::strlen (this->iiop_endpoint_->host ()) // chars in host name
00135     + sizeof (':')                                 // delimiter
00136     + ACE_OS::strlen ("65536")                     // max port
00137     + sizeof ('\0');
00138 
00139   if (length < actual_len)
00140     return -1;
00141 
00142   ACE_OS::sprintf (buffer,
00143                    "%s:%d",
00144                    this->iiop_endpoint_->host (),
00145                    this->ssl_component_.port);
00146 
00147   return 0;
00148 }
00149 
00150 
00151 TAO_Endpoint *
00152 TAO_SSLIOP_Endpoint::next (void)
00153 {
00154   return this->next_;
00155 }
00156 
00157 CORBA::Boolean
00158 TAO_SSLIOP_Endpoint::is_equivalent (const TAO_Endpoint *other_endpoint)
00159 {
00160   TAO_Endpoint *endpt = const_cast<TAO_Endpoint *> (other_endpoint);
00161 
00162   TAO_SSLIOP_Endpoint *endpoint =
00163     dynamic_cast<TAO_SSLIOP_Endpoint *> (endpt);
00164 
00165   if (endpoint == 0)
00166     return 0;
00167 
00168   ::Security::EstablishTrust t = endpoint->trust ();
00169 
00170   if ((this->ssl_component_.port != 0
00171        && endpoint->ssl_component_.port != 0
00172        && this->ssl_component_.port != endpoint->ssl_component_.port)
00173       || this->qop_ != endpoint->qop ()
00174       || this->trust_.trust_in_target != t.trust_in_target
00175       || this->trust_.trust_in_client != t.trust_in_client
00176       || (!CORBA::is_nil (this->credentials_.in ())
00177           && !(*this->credentials_.in () == *endpoint->credentials ())))
00178   {
00179     return 0;
00180   }
00181 
00182   // Comparing the underlying iiop endpoints is wrong, as their port
00183   // numbers often may not make sense. Or may not being used anyway.
00184   // Therefore, we only need to directly compare the hosts. See also the
00185   // comments in the hash() method.
00186   if (this->iiop_endpoint() == 0 || endpoint->iiop_endpoint() == 0)
00187     return 0;
00188 
00189   if ((ACE_OS::strcmp (this->iiop_endpoint()->host (), 
00190                        endpoint->iiop_endpoint()->host ()) != 0))
00191     return 0;
00192 
00193   return 1;
00194 }
00195 
00196 TAO_Endpoint *
00197 TAO_SSLIOP_Endpoint::duplicate (void)
00198 {
00199   TAO_SSLIOP_Endpoint *endpoint = 0;
00200 
00201   // @@ We need to set the priority of the newly formed endpoint. It
00202   // shouldnt be a problem as long as SSL is not used with RTCORBA.
00203   ACE_NEW_RETURN (endpoint,
00204                   TAO_SSLIOP_Endpoint (&this->ssl_component_,
00205                                          0),
00206                   0);
00207 
00208   if (this->credentials_set_)
00209     endpoint->set_sec_attrs (this->qop_,this->trust_, this->credentials_.in());
00210 
00211   endpoint->iiop_endpoint (this->iiop_endpoint_, true);
00212   endpoint->hash_val_ = this->hash_val_;
00213   return endpoint;
00214 }
00215 
00216 CORBA::ULong
00217 TAO_SSLIOP_Endpoint::hash (void)
00218 {
00219   // there is actually the potential for a race of the inverse case,
00220   // since setting the security attributes will reset the hash_val_,
00221   // it is possible this test to pass, but then have the hash reset
00222   // before the value is returned.
00223   if (this->hash_val_ != 0)
00224     return this->hash_val_;
00225 
00226   // Do this with no locks held, as it may try to acquire it, too.
00227   const ACE_INET_Addr &oaddr = this->object_addr();
00228 
00229   { // nested scope for the lock
00230     ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
00231                       guard,
00232                       this->addr_lookup_lock_,
00233                       this->hash_val_);
00234     // .. DCL
00235     if (this->hash_val_ != 0)
00236       return this->hash_val_;
00237 
00238 
00239     // Note that we are not using the underlying IIOP endpoint's hash
00240     // value in order to avoid the influence of the IIOP port number,
00241     // since it is ignored anyway. When it features a
00242     // purely fictional port number, as when accepting an SSL
00243     // connection, the unsecured port is undefined and
00244     // had we used it in computing the hash it would have broken the
00245     // bi-directional support - as the 'guessed' IIOP port value will
00246     // hardly match the one specified in the bi-dir service context.
00247     this->hash_val_ =
00248       oaddr.get_ip_address ()
00249       + this->ssl_component_.port;
00250   }
00251 
00252   return this->hash_val_;
00253 }
00254 
00255 
00256 const ACE_INET_Addr &
00257 TAO_SSLIOP_Endpoint::object_addr (void) const
00258 {
00259   // The object_addr_ is initialized here, rather than at IOR decode
00260   // time for several reasons:
00261   //   1. A request on the object may never be invoked.
00262   //   2. The DNS setup may have changed dynamically.
00263   //   ...etc..
00264 
00265   // Double checked locking optimization.
00266   if (this->object_addr_.get_type () != AF_INET)
00267     {
00268       const ACE_INET_Addr &iiop_addr = this->iiop_endpoint_->object_addr ();
00269 
00270       ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
00271                         guard,
00272                         this->addr_lookup_lock_,
00273                         this->object_addr_);
00274 
00275       if (this->object_addr_.get_type () != AF_INET)
00276         {
00277           this->object_addr_ = iiop_addr;
00278           this->object_addr_.set_port_number (this->ssl_component_.port);
00279         }
00280     }
00281 
00282   return this->object_addr_;
00283 }
00284 
00285 void
00286 TAO_SSLIOP_Endpoint::set_sec_attrs (::Security::QOP q,
00287                                     const ::Security::EstablishTrust &t,
00288                                     const TAO::SSLIOP::OwnCredentials_ptr c)
00289 {
00290   if (this->credentials_set_)
00291     return;
00292 
00293   ACE_GUARD (TAO_SYNCH_MUTEX,
00294              guard,
00295              this->addr_lookup_lock_);
00296 
00297   // double-check
00298   if (this->credentials_set_)
00299     return;
00300 
00301   this->qop_ = q;
00302   this->trust_ = t;
00303   this->credentials_ = TAO::SSLIOP::OwnCredentials::_duplicate (c);
00304   this->credentials_set_ = 1;
00305 
00306   // reset the hash value to force a recomputation.
00307   this->hash_val_ = 0;
00308 }
00309 
00310 
00311 
00312 
00313 TAO_SSLIOP_Synthetic_Endpoint::~TAO_SSLIOP_Synthetic_Endpoint ()
00314 {
00315 }
00316 
00317 TAO_SSLIOP_Synthetic_Endpoint::TAO_SSLIOP_Synthetic_Endpoint (const ::SSLIOP::SSL *ssl)
00318   : TAO_SSLIOP_Endpoint (ssl, 0)
00319 {
00320 }
00321 
00322 
00323 TAO_SSLIOP_Synthetic_Endpoint::TAO_SSLIOP_Synthetic_Endpoint (TAO_IIOP_Endpoint *iiop_endp)
00324   : TAO_SSLIOP_Endpoint ((const ::SSLIOP::SSL *)0, iiop_endp)
00325 {
00326    this->ssl_component_.port = iiop_endp->port ();
00327 }
00328 
00329 
00330 CORBA::Boolean
00331 TAO_SSLIOP_Synthetic_Endpoint::is_equivalent (const TAO_Endpoint *other_endpoint)
00332 {
00333   TAO_Endpoint *endpt = const_cast<TAO_Endpoint *> (other_endpoint);
00334 
00335   TAO_SSLIOP_Endpoint *endpoint =
00336     dynamic_cast<TAO_SSLIOP_Endpoint *> (endpt);
00337 
00338   if (endpoint == 0)
00339     return 0;
00340   
00341   if ((this->ssl_component ().port != 0
00342        && endpoint->ssl_component ().port != 0
00343        && this->ssl_component ().port != endpoint->ssl_component ().port)
00344        || this->qop () < endpoint->qop ())
00345   {
00346     return 0;
00347   }
00348 
00349   // Comparing the underlying iiop endpoints is wrong, as their port
00350   // numbers often may not make sense, or are not being used anyway.
00351   // Therefore, directly comparing the hosts at this point. See also the
00352   // comments in the hash() method
00353   if (this->iiop_endpoint() == 0 || endpoint->iiop_endpoint() == 0)
00354     return 0;
00355 
00356   if ((ACE_OS::strcmp (this->iiop_endpoint()->host (), 
00357                        endpoint->iiop_endpoint()->host ()) != 0))
00358     return 0;
00359 
00360   return 1;
00361 }
00362 
00363 TAO_Endpoint *
00364 TAO_SSLIOP_Synthetic_Endpoint::duplicate (void)
00365 {
00366   TAO_SSLIOP_Synthetic_Endpoint *endpoint = 0;
00367 
00368   // @@ We need to set the priority of the newly formed endpoint. It
00369   // shouldnt be a problem as long as SSL is not used with RTCORBA.
00370   ACE_NEW_RETURN (endpoint,
00371                   TAO_SSLIOP_Synthetic_Endpoint (&(this->ssl_component ())),
00372                   0);
00373 
00374   if (this->credentials_set())
00375     endpoint->set_sec_attrs (this->qop (),this->trust (), this->credentials ());
00376 
00377   endpoint->iiop_endpoint (this->iiop_endpoint (), true);
00378   endpoint->hash_val_ = this->hash ();
00379   return endpoint;
00380 }
00381 
00382 TAO_END_VERSIONED_NAMESPACE_DECL

Generated on Thu Nov 9 13:54:14 2006 for TAO_SSLIOP by doxygen 1.3.6