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            "$Id: SSLIOP_Endpoint.cpp 79267 2007-08-08 15:51:45Z mesnier_p $")
00014 
00015 
00016 #if !defined (__ACE_INLINE__)
00017 # include "orbsvcs/SSLIOP/SSLIOP_Endpoint.inl"
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 
00090 TAO_SSLIOP_Endpoint &
00091 TAO_SSLIOP_Endpoint::operator= (const TAO_SSLIOP_Endpoint &other)
00092 {
00093   this->object_addr_ = other.object_addr_;
00094   this->qop_ = other.qop_;
00095   this->trust_ = other.trust_;
00096   this->ssl_component_ = other.ssl_component_;
00097 
00098   this->next_ = 0; // do not copy list membership, since we are only cloning the values
00099 
00100   this->iiop_endpoint(other.iiop_endpoint_,
00101                       other.destroy_iiop_endpoint_);
00102   return *this;
00103 }
00104 
00105 TAO_SSLIOP_Endpoint::~TAO_SSLIOP_Endpoint (void)
00106 {
00107   if (this->destroy_iiop_endpoint_)
00108     delete this->iiop_endpoint_;
00109 }
00110 
00111 #if 0
00112 static void
00113 dump_endpoint (const char* msg, const TAO_Endpoint *other_endpoint)
00114 {
00115 
00116   TAO_Endpoint *endpt = const_cast<TAO_Endpoint *> (other_endpoint);
00117 
00118   TAO_SSLIOP_Endpoint *endpoint =
00119     dynamic_cast<TAO_SSLIOP_Endpoint *> (endpt);
00120 
00121   if (endpoint == 0)
00122   {
00123     ACE_DEBUG ((LM_DEBUG, "TAO (%P|%t) endpoint - %s: Unable to cast an endpoint to SSLIOP_Endpoint\n", msg));
00124     return;
00125   }
00126 
00127   char hostaddr[MAXHOSTNAMELEN + 16];
00128   int gothost = endpoint->addr_to_string (hostaddr, sizeof hostaddr);
00129 
00130   ACE_DEBUG ((LM_INFO, "TAO (%P|%t) SSLIOPEndpoint %s - %@ {%s, ssl=%d, iiop=%d,"
00131                 " qop=%d, trst=(%d,%d), c=%@, crdh=0x%x}, h=0x%x\n",
00132                 msg,
00133                 endpoint,
00134                 (gothost == 0 ? hostaddr : "*UNKNOWN*"),
00135                 endpoint->ssl_component ().port ,
00136                 endpoint->iiop_endpoint ()->port (),
00137                 endpoint->qop() ,
00138                 endpoint->trust().trust_in_target ,
00139                 endpoint->trust().trust_in_client ,
00140                 endpoint->credentials() ,
00141                 (endpoint->credentials_set () ? endpoint->credentials()->hash () : 0) ,
00142                 endpoint->hash ()));
00143 }
00144 #endif /* 0 */
00145 
00146 int
00147 TAO_SSLIOP_Endpoint::addr_to_string (char *buffer, size_t length)
00148 {
00149   size_t actual_len =
00150     ACE_OS::strlen (this->iiop_endpoint_->host ()) // chars in host name
00151     + sizeof (':')                                 // delimiter
00152     + ACE_OS::strlen ("65536")                     // max port
00153     + sizeof ('\0');
00154 
00155   if (length < actual_len)
00156     return -1;
00157 
00158   ACE_OS::sprintf (buffer,
00159                    "%s:%d",
00160                    this->iiop_endpoint_->host (),
00161                    this->ssl_component_.port);
00162 
00163   return 0;
00164 }
00165 
00166 
00167 TAO_Endpoint *
00168 TAO_SSLIOP_Endpoint::next (void)
00169 {
00170   return this->next_;
00171 }
00172 
00173 CORBA::Boolean
00174 TAO_SSLIOP_Endpoint::is_equivalent (const TAO_Endpoint *other_endpoint)
00175 {
00176   TAO_Endpoint *endpt = const_cast<TAO_Endpoint *> (other_endpoint);
00177 
00178   TAO_SSLIOP_Endpoint *endpoint =
00179     dynamic_cast<TAO_SSLIOP_Endpoint *> (endpt);
00180 
00181   if (endpoint == 0)
00182     return 0;
00183 
00184   ::Security::EstablishTrust t = endpoint->trust ();
00185 
00186   if ((this->ssl_component_.port != 0
00187        && endpoint->ssl_component_.port != 0
00188        && this->ssl_component_.port != endpoint->ssl_component_.port)
00189       || this->qop_ != endpoint->qop ()
00190       || this->trust_.trust_in_target != t.trust_in_target
00191       || this->trust_.trust_in_client != t.trust_in_client
00192       || (!CORBA::is_nil (this->credentials_.in ())
00193           && !(*this->credentials_.in () == *endpoint->credentials ())))
00194   {
00195     return 0;
00196   }
00197 
00198   // Comparing the underlying iiop endpoints is wrong, as their port
00199   // numbers often may not make sense. Or may not being used anyway.
00200   // Therefore, we only need to directly compare the hosts. See also the
00201   // comments in the hash() method.
00202   if (this->iiop_endpoint() == 0 || endpoint->iiop_endpoint() == 0)
00203     return 0;
00204 
00205   if ((ACE_OS::strcmp (this->iiop_endpoint()->host (),
00206                        endpoint->iiop_endpoint()->host ()) != 0))
00207     return 0;
00208 
00209   return 1;
00210 }
00211 
00212 TAO_Endpoint *
00213 TAO_SSLIOP_Endpoint::duplicate (void)
00214 {
00215   TAO_SSLIOP_Endpoint *endpoint = 0;
00216 
00217   // @@ We need to set the priority of the newly formed endpoint. It
00218   // shouldnt be a problem as long as SSL is not used with RTCORBA.
00219   ACE_NEW_RETURN (endpoint,
00220                   TAO_SSLIOP_Endpoint (&this->ssl_component_,
00221                                          0),
00222                   0);
00223 
00224   if (this->credentials_set_)
00225     endpoint->set_sec_attrs (this->qop_,this->trust_, this->credentials_.in());
00226 
00227   endpoint->iiop_endpoint (this->iiop_endpoint_, true);
00228   endpoint->hash_val_ = this->hash_val_;
00229   return endpoint;
00230 }
00231 
00232 CORBA::ULong
00233 TAO_SSLIOP_Endpoint::hash (void)
00234 {
00235   // there is actually the potential for a race of the inverse case,
00236   // since setting the security attributes will reset the hash_val_,
00237   // it is possible this test to pass, but then have the hash reset
00238   // before the value is returned.
00239   if (this->hash_val_ != 0)
00240     return this->hash_val_;
00241 
00242   // Do this with no locks held, as it may try to acquire it, too.
00243   const ACE_INET_Addr &oaddr = this->object_addr();
00244 
00245   { // nested scope for the lock
00246     ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
00247                       guard,
00248                       this->addr_lookup_lock_,
00249                       this->hash_val_);
00250     // .. DCL
00251     if (this->hash_val_ != 0)
00252       return this->hash_val_;
00253 
00254 
00255     // Note that we are not using the underlying IIOP endpoint's hash
00256     // value in order to avoid the influence of the IIOP port number,
00257     // since it is ignored anyway. When it features a
00258     // purely fictional port number, as when accepting an SSL
00259     // connection, the unsecured port is undefined and
00260     // had we used it in computing the hash it would have broken the
00261     // bi-directional support - as the 'guessed' IIOP port value will
00262     // hardly match the one specified in the bi-dir service context.
00263     this->hash_val_ =
00264       oaddr.hash ()
00265       + this->ssl_component_.port;
00266   }
00267 
00268   return this->hash_val_;
00269 }
00270 
00271 
00272 const ACE_INET_Addr &
00273 TAO_SSLIOP_Endpoint::object_addr (void) const
00274 {
00275   // The object_addr_ is initialized here, rather than at IOR decode
00276   // time for several reasons:
00277   //   1. A request on the object may never be invoked.
00278   //   2. The DNS setup may have changed dynamically.
00279   //   ...etc..
00280 
00281   // Double checked locking optimization.
00282   if (this->object_addr_.get_type () != AF_INET
00283 #if defined (ACE_HAS_IPV6)
00284       && this->object_addr_.get_type () != AF_INET6
00285 #endif /* ACE_HAS_IPV6 */
00286      )
00287     {
00288       const ACE_INET_Addr &iiop_addr = this->iiop_endpoint_->object_addr ();
00289 
00290       ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
00291                         guard,
00292                         this->addr_lookup_lock_,
00293                         this->object_addr_);
00294 
00295       if (this->object_addr_.get_type () != AF_INET
00296 #if defined (ACE_HAS_IPV6)
00297           && this->object_addr_.get_type () != AF_INET6
00298 #endif /* ACE_HAS_IPV6 */
00299      )
00300         {
00301           this->object_addr_ = iiop_addr;
00302           this->object_addr_.set_port_number (this->ssl_component_.port);
00303         }
00304     }
00305 
00306   return this->object_addr_;
00307 }
00308 
00309 void
00310 TAO_SSLIOP_Endpoint::set_sec_attrs (::Security::QOP q,
00311                                     const ::Security::EstablishTrust &t,
00312                                     const TAO::SSLIOP::OwnCredentials_ptr c)
00313 {
00314   if (this->credentials_set_)
00315     return;
00316 
00317   ACE_GUARD (TAO_SYNCH_MUTEX,
00318              guard,
00319              this->addr_lookup_lock_);
00320 
00321   // double-check
00322   if (this->credentials_set_)
00323     return;
00324 
00325   this->qop_ = q;
00326   this->trust_ = t;
00327   this->credentials_ = TAO::SSLIOP::OwnCredentials::_duplicate (c);
00328   this->credentials_set_ = 1;
00329 
00330   // reset the hash value to force a recomputation.
00331   this->hash_val_ = 0;
00332 }
00333 
00334 
00335 
00336 
00337 TAO_SSLIOP_Synthetic_Endpoint::~TAO_SSLIOP_Synthetic_Endpoint ()
00338 {
00339 }
00340 
00341 TAO_SSLIOP_Synthetic_Endpoint::TAO_SSLIOP_Synthetic_Endpoint (const ::SSLIOP::SSL *ssl)
00342   : TAO_SSLIOP_Endpoint (ssl, 0)
00343 {
00344 }
00345 
00346 
00347 TAO_SSLIOP_Synthetic_Endpoint::TAO_SSLIOP_Synthetic_Endpoint (TAO_IIOP_Endpoint *iiop_endp)
00348   : TAO_SSLIOP_Endpoint ((const ::SSLIOP::SSL *)0, iiop_endp)
00349 {
00350    this->ssl_component_.port = iiop_endp->port ();
00351 }
00352 
00353 
00354 CORBA::Boolean
00355 TAO_SSLIOP_Synthetic_Endpoint::is_equivalent (const TAO_Endpoint *other_endpoint)
00356 {
00357   TAO_Endpoint *endpt = const_cast<TAO_Endpoint *> (other_endpoint);
00358 
00359   TAO_SSLIOP_Endpoint *endpoint =
00360     dynamic_cast<TAO_SSLIOP_Endpoint *> (endpt);
00361 
00362   if (endpoint == 0)
00363     return 0;
00364 
00365   if ((this->ssl_component ().port != 0
00366        && endpoint->ssl_component ().port != 0
00367        && this->ssl_component ().port != endpoint->ssl_component ().port)
00368        || this->qop () < endpoint->qop ())
00369   {
00370     return 0;
00371   }
00372 
00373   // Comparing the underlying iiop endpoints is wrong, as their port
00374   // numbers often may not make sense, or are not being used anyway.
00375   // Therefore, directly comparing the hosts at this point. See also the
00376   // comments in the hash() method
00377   if (this->iiop_endpoint() == 0 || endpoint->iiop_endpoint() == 0)
00378     return 0;
00379 
00380   if ((ACE_OS::strcmp (this->iiop_endpoint()->host (),
00381                        endpoint->iiop_endpoint()->host ()) != 0))
00382     return 0;
00383 
00384   return 1;
00385 }
00386 
00387 TAO_Endpoint *
00388 TAO_SSLIOP_Synthetic_Endpoint::duplicate (void)
00389 {
00390   TAO_SSLIOP_Synthetic_Endpoint *endpoint = 0;
00391 
00392   // @@ We need to set the priority of the newly formed endpoint. It
00393   // shouldnt be a problem as long as SSL is not used with RTCORBA.
00394   ACE_NEW_RETURN (endpoint,
00395                   TAO_SSLIOP_Synthetic_Endpoint (&(this->ssl_component ())),
00396                   0);
00397 
00398   if (this->credentials_set())
00399     endpoint->set_sec_attrs (this->qop (),this->trust (), this->credentials ());
00400 
00401   endpoint->iiop_endpoint (this->iiop_endpoint (), true);
00402   endpoint->hash_val_ = this->hash ();
00403   return endpoint;
00404 }
00405 
00406 TAO_END_VERSIONED_NAMESPACE_DECL

Generated on Tue Feb 2 17:48:44 2010 for TAO_SSLIOP by  doxygen 1.4.7