SSLIOP_Profile.cpp

Go to the documentation of this file.
00001 #include "orbsvcs/SSLIOP/SSLIOP_Profile.h"
00002 #include "orbsvcs/SSLIOP/ssl_endpointsC.h"
00003 #include "tao/CDR.h"
00004 #include "tao/Environment.h"
00005 #include "ace/OS_NS_string.h"
00006 
00007 
00008 ACE_RCSID (SSLIOP,
00009            SSLIOP_Profile,
00010            "SSLIOP_Profile.cpp,v 1.38 2006/03/14 06:14:35 jtc Exp")
00011 
00012 
00013 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00014 
00015 TAO_SSLIOP_Profile::TAO_SSLIOP_Profile (const ACE_INET_Addr & addr,
00016                                const TAO::ObjectKey & object_key,
00017                                const TAO_GIOP_Message_Version & version,
00018                                TAO_ORB_Core * orb_core,
00019                                const ::SSLIOP::SSL * ssl_component)
00020   : TAO_IIOP_Profile (addr,
00021                       object_key,
00022                       version,
00023                       orb_core),
00024   ssl_endpoint_ (ssl_component, 0),
00025   ssl_only_ (0)
00026 {
00027   this->ssl_endpoint_.iiop_endpoint (&this->endpoint_, true);
00028 }
00029 
00030 TAO_SSLIOP_Profile::TAO_SSLIOP_Profile (const char * host,
00031                                CORBA::UShort port,
00032                                const TAO::ObjectKey & object_key,
00033                                const ACE_INET_Addr & addr,
00034                                const TAO_GIOP_Message_Version & version,
00035                                TAO_ORB_Core * orb_core,
00036                                const ::SSLIOP::SSL * ssl_component)
00037   : TAO_IIOP_Profile (host,
00038                       port,
00039                       object_key,
00040                       addr,
00041                       version,
00042                       orb_core),
00043   ssl_endpoint_ (ssl_component, 0),
00044   ssl_only_ (0)
00045 {
00046   this->ssl_endpoint_.iiop_endpoint (&this->endpoint_, true);
00047 }
00048 
00049 TAO_SSLIOP_Profile::TAO_SSLIOP_Profile (TAO_ORB_Core * orb_core,
00050                                const ::SSLIOP::SSL * ssl_component)
00051   : TAO_IIOP_Profile (orb_core),
00052     ssl_endpoint_ (ssl_component, 0),
00053     ssl_only_ (0)
00054 {
00055   this->ssl_endpoint_.iiop_endpoint (&this->endpoint_, true);
00056 }
00057 
00058 TAO_SSLIOP_Profile::TAO_SSLIOP_Profile (TAO_ORB_Core * orb_core, int ssl_only)
00059   : TAO_IIOP_Profile (orb_core),
00060     ssl_endpoint_ (0, 0),
00061     ssl_only_ (ssl_only)
00062 {
00063   this->ssl_endpoint_.iiop_endpoint (&this->endpoint_, true);
00064 }
00065 
00066 TAO_SSLIOP_Profile::~TAO_SSLIOP_Profile (void)
00067 {
00068   // Clean up the list of endpoints since we own it.
00069   // Skip the head, since it is not dynamically allocated.
00070   TAO_Endpoint *tmp = 0;
00071 
00072   for (TAO_Endpoint *next = this->ssl_endpoint_.next ();
00073        next != 0;
00074        next = tmp)
00075     {
00076       tmp = next->next ();
00077       delete next;
00078     }
00079 }
00080 
00081 // return codes:
00082 // -1 -> error
00083 //  0 -> can't understand this version
00084 //  1 -> success.
00085 int
00086 TAO_SSLIOP_Profile::decode (TAO_InputCDR & cdr)
00087 {
00088   int r = this->TAO_IIOP_Profile::decode (cdr);
00089   if (r != 1)
00090     return r;
00091 
00092   // Attempt to decode SSLIOP::SSL tagged component.  It may not be
00093   // there if we are dealing with pure IIOP profile.
00094   int ssl_component_found = 0;
00095   IOP::TaggedComponent component;
00096   component.tag = ::SSLIOP::TAG_SSL_SEC_TRANS;
00097 
00098   if (this->tagged_components ().get_component (component))
00099     {
00100       TAO_InputCDR cdr (reinterpret_cast<const char*> (
00101                           component.component_data.get_buffer ()),
00102                         component.component_data.length ());
00103       CORBA::Boolean byte_order;
00104       if ((cdr >> ACE_InputCDR::to_boolean (byte_order)) == 0)
00105         return -1;
00106       cdr.reset_byte_order (static_cast<int> (byte_order));
00107 
00108       if (cdr >> this->ssl_endpoint_.ssl_component_)
00109         ssl_component_found = 1;
00110       else
00111         return -1;
00112     }
00113 
00114   // Since IIOP portion of the profile has already been decoded, we
00115   // know how many endpoints it should contain and can finish
00116   // initialization accordingly.
00117   if (this->count_ < 2)
00118     {
00119       // This profile contains only one endpoint.  Finish initializing
00120       // it.
00121       this->ssl_endpoint_.iiop_endpoint (&this->endpoint_, true);
00122       this->ssl_endpoint_.priority (this->endpoint_.priority ());
00123       return 1;
00124     }
00125   else
00126     {
00127       // This profile contains more than one endpoint.
00128       if (ssl_component_found)
00129         {
00130           // It is true ssl profile, i.e., not just IIOP, so must have
00131           // ssl endpoints encoded.
00132 
00133           if (this->decode_tagged_endpoints () == -1)
00134             return -1;
00135 
00136           return 1;
00137         }
00138       else
00139         {
00140           // IIOP profile - doesn't have ssl endpoints encoded.  We
00141           // must create 'dummy' ssl endpoint list anyways, in order to
00142           // make iiop endpoints accessable and usable.
00143           for (size_t i = 0;
00144                i < this->count_;
00145                ++i)
00146             {
00147               TAO_SSLIOP_Endpoint *endpoint = 0;
00148               ACE_NEW_RETURN (endpoint,
00149                               TAO_SSLIOP_Endpoint (0, 0),
00150                               -1);
00151               this->add_endpoint (endpoint);
00152             }
00153 
00154           // Now that we have a complete list of ssl endpoins, we can
00155           // connect them with their iiop counterparts.
00156           TAO_IIOP_Endpoint *iiop_endp = &this->endpoint_;
00157 
00158           for (TAO_SSLIOP_Endpoint * ssl_endp = &this->ssl_endpoint_;
00159                ssl_endp != 0;
00160                ssl_endp = ssl_endp->next_)
00161             {
00162               ssl_endp->iiop_endpoint (iiop_endp, true);
00163               ssl_endp->priority (iiop_endp->priority ());
00164               iiop_endp = iiop_endp->next_;
00165             }
00166 
00167           return 1;
00168         }
00169     }
00170 }
00171 
00172 CORBA::Boolean
00173 TAO_SSLIOP_Profile::do_is_equivalent (const TAO_Profile * other_profile)
00174 {
00175   const TAO_SSLIOP_Profile *op =
00176     dynamic_cast<const TAO_SSLIOP_Profile *> (other_profile);
00177 
00178   // Make sure we have a TAO_SSLIOP_Profile.
00179   if (op == 0)
00180     return 0;
00181 
00182   // Now verify TAO_SSLIOP_Endpoint equivalence.
00183   const TAO_SSLIOP_Endpoint *other_endp = &op->ssl_endpoint_;
00184   for (TAO_SSLIOP_Endpoint *endp = &this->ssl_endpoint_;
00185        endp != 0;
00186        endp = endp->next_)
00187     {
00188       if (endp->is_equivalent (other_endp))
00189         other_endp = other_endp->next_;
00190       else
00191         return 0;
00192     }
00193 
00194   return 1;
00195 }
00196 
00197 TAO_Endpoint*
00198 TAO_SSLIOP_Profile::endpoint (void)
00199 {
00200   return &this->ssl_endpoint_;
00201 }
00202 
00203 void
00204 TAO_SSLIOP_Profile::add_endpoint (TAO_SSLIOP_Endpoint * endp)
00205 {
00206   endp->next_ = this->ssl_endpoint_.next_;
00207   this->ssl_endpoint_.next_ = endp;
00208 
00209   // We do not want to add our IIOP endpoint counterpart when we are
00210   // decoding a profile, and IIOP endpoints have been added before we
00211   // even get to SSLIOP-specific decoding.
00212   if (endp->iiop_endpoint () != 0)
00213     this->TAO_IIOP_Profile::add_endpoint (endp->iiop_endpoint ());
00214 }
00215 
00216 int
00217 TAO_SSLIOP_Profile::encode_endpoints (void)
00218 {
00219   // If we have more than one endpoint, we encode info about others
00220   // into a tagged component for wire transfer.
00221   if (this->count_ > 1)
00222     {
00223       // Encode all endpoints except the first one, since it is always
00224       // transferred through standard profile component.
00225 
00226       // Create a data structure and fill it with endpoint info for wire
00227       // transfer.
00228       TAO_SSLEndpointSequence endpoints;
00229       endpoints.length (this->count_ - 1);
00230 
00231       const TAO_SSLIOP_Endpoint *endpoint = this->ssl_endpoint_.next_;
00232       for (size_t i = 0;
00233            i < this->count_ - 1;
00234            ++i)
00235         {
00236           endpoints[i] = endpoint->ssl_component ();
00237           endpoint = endpoint->next_;
00238         }
00239 
00240       // Encode the data structure.
00241       TAO_OutputCDR out_cdr;
00242       if ((out_cdr << ACE_OutputCDR::from_boolean (TAO_ENCAP_BYTE_ORDER)
00243            == 0)
00244           || (out_cdr << endpoints) == 0)
00245         return -1;
00246 
00247       const CORBA::ULong length = out_cdr.total_length ();
00248 
00249       IOP::TaggedComponent tagged_component;
00250       tagged_component.tag = TAO::TAG_SSL_ENDPOINTS;
00251       tagged_component.component_data.length (length);
00252       CORBA::Octet *buf =
00253         tagged_component.component_data.get_buffer ();
00254 
00255       for (const ACE_Message_Block *iterator = out_cdr.begin ();
00256            iterator != 0;
00257            iterator = iterator->cont ())
00258         {
00259           CORBA::ULong i_length = iterator->length ();
00260           ACE_OS::memcpy (buf, iterator->rd_ptr (), i_length);
00261 
00262           buf += i_length;
00263         }
00264 
00265       // Add component with encoded endpoint data to this profile's
00266       // TaggedComponents.
00267       tagged_components_.set_component (tagged_component);
00268     }
00269 
00270   return this->TAO_IIOP_Profile::encode_endpoints ();
00271 }
00272 
00273 int
00274 TAO_SSLIOP_Profile::decode_tagged_endpoints (void)
00275 {
00276   IOP::TaggedComponent tagged_component;
00277   tagged_component.tag = TAO::TAG_SSL_ENDPOINTS;
00278 
00279   if (this->tagged_components_.get_component (tagged_component))
00280     {
00281       const CORBA::Octet *buf =
00282         tagged_component.component_data.get_buffer ();
00283 
00284       TAO_InputCDR in_cdr (reinterpret_cast<const char* > (buf),
00285                            tagged_component.component_data.length ());
00286 
00287       // Extract the Byte Order.
00288       CORBA::Boolean byte_order;
00289       if ((in_cdr >> ACE_InputCDR::to_boolean (byte_order)) == 0)
00290         return -1;
00291       in_cdr.reset_byte_order (static_cast<int> (byte_order));
00292 
00293       // Extract endpoints sequence.
00294       TAO_SSLEndpointSequence endpoints;
00295       if ((in_cdr >> endpoints) == 0)
00296         return -1;
00297 
00298       // Use information extracted from the tagged component to
00299       // populate the profile.  Begin from the end of the sequence to
00300       // preserve endpoint order, since <add_endpoint> method reverses
00301       // the order of endpoints in the list.
00302       for (CORBA::ULong i = endpoints.length () - 1;
00303            (i + 1) != 0;
00304            --i)
00305         {
00306           TAO_SSLIOP_Endpoint *endpoint = 0;
00307           ACE_NEW_RETURN (endpoint,
00308                           TAO_SSLIOP_Endpoint (0, 0),
00309                           -1);
00310           endpoint->ssl_component_ = endpoints[i];
00311           this->add_endpoint (endpoint);
00312         }
00313 
00314       // Now that we have a complete list of ssl endpoins, we can
00315       // connect them with their iiop counterparts, which have been
00316       // extracted/chained during the IIOP profile decoding.
00317       TAO_IIOP_Endpoint *iiop_endp = &this->endpoint_;
00318 
00319       for (TAO_SSLIOP_Endpoint * ssl_endp = &this->ssl_endpoint_;
00320            ssl_endp != 0;
00321            ssl_endp = ssl_endp->next_)
00322         {
00323           ssl_endp->iiop_endpoint (iiop_endp, true);
00324           ssl_endp->priority (iiop_endp->priority ());
00325           iiop_endp = iiop_endp->next_;
00326         }
00327 
00328       return 0;
00329     }
00330 
00331   // Since this method is only called if we are expecting
00332   // TAO_TAG_SSL_ENDPOINTS component, failure to find it is an error.
00333   return -1;
00334 }
00335 
00336 void
00337 TAO_SSLIOP_Profile::parse_string (const char * ior
00338                                   ACE_ENV_ARG_DECL)
00339 {
00340    TAO_IIOP_Profile::parse_string (ior
00341                                    ACE_ENV_ARG_PARAMETER);
00342    ACE_CHECK;
00343 
00344    this->ssl_endpoint_.iiop_endpoint (&this->endpoint_, true);
00345 
00346    if( ssl_only_)
00347    {
00348       this->ssl_endpoint_.ssl_component_.port = this->endpoint_.port_;
00349 
00350       // Note that the Security::NoProtection bit is cleared since we
00351       // are sure the server supports SSL (we're told so)
00352       ACE_CLR_BITS (this->ssl_endpoint_.ssl_component_.target_supports,
00353             Security::NoProtection);
00354    }
00355 }
00356 
00357 TAO_END_VERSIONED_NAMESPACE_DECL

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