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 "ace/OS_NS_string.h"
00005 
00006 ACE_RCSID (SSLIOP,
00007            SSLIOP_Profile,
00008            "$Id: SSLIOP_Profile.cpp 77784 2007-03-23 13:08:15Z mesnier_p $")
00009 
00010 
00011 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00012 
00013 TAO_SSLIOP_Profile::TAO_SSLIOP_Profile (const ACE_INET_Addr & addr,
00014                                const TAO::ObjectKey & object_key,
00015                                const TAO_GIOP_Message_Version & version,
00016                                TAO_ORB_Core * orb_core,
00017                                const ::SSLIOP::SSL * ssl_component)
00018   : TAO_IIOP_Profile (addr,
00019                       object_key,
00020                       version,
00021                       orb_core),
00022   ssl_endpoint_ (ssl_component, 0),
00023   ssl_only_ (0)
00024 {
00025   this->ssl_endpoint_.iiop_endpoint (&this->endpoint_, true);
00026 }
00027 
00028 TAO_SSLIOP_Profile::TAO_SSLIOP_Profile (const char * host,
00029                                CORBA::UShort port,
00030                                const TAO::ObjectKey & object_key,
00031                                const ACE_INET_Addr & addr,
00032                                const TAO_GIOP_Message_Version & version,
00033                                TAO_ORB_Core * orb_core,
00034                                const ::SSLIOP::SSL * ssl_component)
00035   : TAO_IIOP_Profile (host,
00036                       port,
00037                       object_key,
00038                       addr,
00039                       version,
00040                       orb_core),
00041   ssl_endpoint_ (ssl_component, 0),
00042   ssl_only_ (0)
00043 {
00044   this->ssl_endpoint_.iiop_endpoint (&this->endpoint_, true);
00045 }
00046 
00047 TAO_SSLIOP_Profile::TAO_SSLIOP_Profile (TAO_ORB_Core * orb_core,
00048                                const ::SSLIOP::SSL * ssl_component)
00049   : TAO_IIOP_Profile (orb_core),
00050     ssl_endpoint_ (ssl_component, 0),
00051     ssl_only_ (0)
00052 {
00053   this->ssl_endpoint_.iiop_endpoint (&this->endpoint_, true);
00054 }
00055 
00056 TAO_SSLIOP_Profile::TAO_SSLIOP_Profile (TAO_ORB_Core * orb_core, int ssl_only)
00057   : TAO_IIOP_Profile (orb_core),
00058     ssl_endpoint_ (0, 0),
00059     ssl_only_ (ssl_only)
00060 {
00061   this->ssl_endpoint_.iiop_endpoint (&this->endpoint_, true);
00062 }
00063 
00064 TAO_SSLIOP_Profile::~TAO_SSLIOP_Profile (void)
00065 {
00066   // Clean up the list of endpoints since we own it.
00067   // Skip the head, since it is not dynamically allocated.
00068   TAO_Endpoint *tmp = 0;
00069 
00070   for (TAO_Endpoint *next = this->ssl_endpoint_.next ();
00071        next != 0;
00072        next = tmp)
00073     {
00074       tmp = next->next ();
00075       delete next;
00076     }
00077 }
00078 
00079 // return codes:
00080 // -1 -> error
00081 //  0 -> can't understand this version
00082 //  1 -> success.
00083 int
00084 TAO_SSLIOP_Profile::decode (TAO_InputCDR & cdr)
00085 {
00086   int r = this->TAO_IIOP_Profile::decode (cdr);
00087   if (r != 1)
00088     return r;
00089 
00090   // Attempt to decode SSLIOP::SSL tagged component.  It may not be
00091   // there if we are dealing with pure IIOP profile.
00092   int ssl_component_found = 0;
00093   IOP::TaggedComponent component;
00094   component.tag = ::SSLIOP::TAG_SSL_SEC_TRANS;
00095 
00096   if (this->tagged_components ().get_component (component))
00097     {
00098       TAO_InputCDR cdr (reinterpret_cast<const char*> (
00099                           component.component_data.get_buffer ()),
00100                         component.component_data.length ());
00101       CORBA::Boolean byte_order;
00102       if ((cdr >> ACE_InputCDR::to_boolean (byte_order)) == 0)
00103         return -1;
00104       cdr.reset_byte_order (static_cast<int> (byte_order));
00105 
00106       if (cdr >> this->ssl_endpoint_.ssl_component_)
00107         ssl_component_found = 1;
00108       else
00109         return -1;
00110     }
00111 
00112   // Since IIOP portion of the profile has already been decoded, we
00113   // know how many endpoints it should contain and can finish
00114   // initialization accordingly.
00115   if (this->count_ < 2)
00116     {
00117       // This profile contains only one endpoint.  Finish initializing
00118       // it.
00119       this->ssl_endpoint_.iiop_endpoint (&this->endpoint_, true);
00120       this->ssl_endpoint_.priority (this->endpoint_.priority ());
00121       return 1;
00122     }
00123   else
00124     {
00125       // This profile contains more than one endpoint.
00126       if (ssl_component_found)
00127         {
00128           // It is true ssl profile, i.e., not just IIOP, so must have
00129           // ssl endpoints encoded.
00130 
00131           if (this->decode_tagged_endpoints () == -1)
00132             return -1;
00133 
00134           return 1;
00135         }
00136       else
00137         {
00138           // IIOP profile - doesn't have ssl endpoints encoded.  We
00139           // must create 'dummy' ssl endpoint list anyways, in order to
00140           // make iiop endpoints accessable and usable. Since we've
00141           // already got one ssliop endpoint, only add the extra
00142           // endpoints (count_ - 1).
00143           for (size_t i = 0;
00144                i < this->count_ -1;
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 {
00339    TAO_IIOP_Profile::parse_string (ior);
00340 
00341    this->ssl_endpoint_.iiop_endpoint (&this->endpoint_, true);
00342 
00343    if( ssl_only_)
00344    {
00345       this->ssl_endpoint_.ssl_component_.port = this->endpoint_.port_;
00346 
00347       // Note that the Security::NoProtection bit is cleared since we
00348       // are sure the server supports SSL (we're told so)
00349       ACE_CLR_BITS (this->ssl_endpoint_.ssl_component_.target_supports,
00350             Security::NoProtection);
00351    }
00352 }
00353 
00354 
00355 void
00356 TAO_SSLIOP_Profile::remove_endpoint (TAO_SSLIOP_Endpoint *endp)
00357 {
00358   if (endp == 0)
00359     return;
00360 
00361   // special handling for the target matching the base endpoint
00362   if (endp == &this->ssl_endpoint_)
00363     {
00364       if (--this->count_ > 0)
00365         {
00366           TAO_SSLIOP_Endpoint* ssl_n = this->ssl_endpoint_.next_;
00367           this->ssl_endpoint_ = *ssl_n;
00368           // since the assignment operator does not copy the next_
00369           // pointer, we must do it by hand
00370           this->ssl_endpoint_.next_ = ssl_n->next_;
00371           delete ssl_n;
00372           TAO_IIOP_Endpoint *n = this->endpoint_.next_;
00373           this->endpoint_ = *n;
00374           this->endpoint_.next_ = n->next_;
00375           delete n;
00376         }
00377       return;
00378     }
00379 
00380   TAO_SSLIOP_Endpoint* last = &this->ssl_endpoint_;
00381   TAO_SSLIOP_Endpoint* cur = this->ssl_endpoint_.next_;
00382 
00383   while (cur != 0)
00384   {
00385     if (cur == endp)
00386       break;
00387     last = cur;
00388     cur = cur->next_;
00389   }
00390 
00391   if (cur != 0)
00392   {
00393     TAO_IIOP_Endpoint *base = cur->iiop_endpoint();
00394     last->iiop_endpoint(base->next_, true);
00395     last->next_ = cur->next_;
00396     cur->next_ = 0;
00397     --this->count_;
00398     delete cur;
00399   }
00400 }
00401 
00402 void
00403 TAO_SSLIOP_Profile::remove_generic_endpoint (TAO_Endpoint *ep)
00404 {
00405   this->remove_endpoint(dynamic_cast<TAO_SSLIOP_Endpoint *>(ep));
00406 }
00407 
00408 TAO_END_VERSIONED_NAMESPACE_DECL

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