summaryrefslogtreecommitdiff
path: root/TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_Acceptor.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_Acceptor.cpp')
-rw-r--r--TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_Acceptor.cpp687
1 files changed, 687 insertions, 0 deletions
diff --git a/TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_Acceptor.cpp b/TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_Acceptor.cpp
new file mode 100644
index 00000000000..2b974c46852
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_Acceptor.cpp
@@ -0,0 +1,687 @@
+#include "orbsvcs/SSLIOP/SSLIOP_Acceptor.h"
+#include "orbsvcs/SSLIOP/SSLIOP_Profile.h"
+
+#include "tao/MProfile.h"
+#include "tao/ORB_Core.h"
+#include "tao/Server_Strategy_Factory.h"
+#include "tao/Codeset_Manager.h"
+#include "tao/CDR.h"
+#include "tao/debug.h"
+
+#if !defined(__ACE_INLINE__)
+#include "orbsvcs/SSLIOP/SSLIOP_Acceptor.inl"
+#endif /* __ACE_INLINE__ */
+
+
+ACE_RCSID (SSLIOP,
+ SSLIOP_Acceptor,
+ "$Id$")
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+TAO::SSLIOP::Acceptor::Acceptor (::Security::QOP qop,
+ const ACE_Time_Value & timeout)
+ : TAO::IIOP_SSL_Acceptor (),
+ ssl_acceptor_ (),
+ creation_strategy_ (0),
+ concurrency_strategy_ (0),
+ accept_strategy_ (0),
+ timeout_ (timeout)
+{
+ // --- CSIv1 ---
+
+ // 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.
+ ACE_SET_BITS (this->ssl_component_.target_supports,
+ ::Security::Integrity
+ | ::Security::Confidentiality
+ | ::Security::EstablishTrustInTarget
+ | ::Security::NoDelegation);
+
+ // Initialize the default SSL port to zero (wild card port).
+ this->ssl_component_.port = 0;
+
+ // @@ This should go away once we support setting security
+ // association options through policies.
+ if (qop == ::Security::SecQOPNoProtection)
+ ACE_SET_BITS (this->ssl_component_.target_supports,
+ ::Security::NoProtection);
+
+
+ // --- CSIv2 ---
+
+ // Clear all bits in the CSIIOP::TLS_SEC_TRANS association option
+ // fields.
+ this->csiv2_component_.target_supports = 0;
+ this->csiv2_component_.target_requires = 0;
+
+ // SSLIOP requires these CSIIOP::AssociationOptions by default.
+ ACE_SET_BITS (this->csiv2_component_.target_requires,
+ CSIIOP::Integrity
+ | CSIIOP::Confidentiality
+ | CSIIOP::NoDelegation);
+
+ // SSLIOP supports these CSIIOP::AssociationOptions by default.
+ ACE_SET_BITS (this->csiv2_component_.target_supports,
+ CSIIOP::Integrity
+ | CSIIOP::Confidentiality
+ | CSIIOP::EstablishTrustInTarget
+ | CSIIOP::NoDelegation);
+
+ // @@ This should go away once we support setting security
+ // association options through policies.
+ if (qop == CSIIOP::NoProtection)
+ ACE_SET_BITS (this->csiv2_component_.target_supports,
+ CSIIOP::NoProtection);
+}
+
+TAO::SSLIOP::Acceptor::~Acceptor (void)
+{
+ // Make sure we are closed before we start destroying the
+ // strategies.
+ this->close ();
+
+ delete this->creation_strategy_;
+ delete this->concurrency_strategy_;
+ delete this->accept_strategy_;
+}
+
+int
+TAO::SSLIOP::Acceptor::create_profile (const TAO::ObjectKey &object_key,
+ TAO_MProfile &mprofile,
+ CORBA::Short priority)
+{
+ // Sanity check.
+ if (this->endpoint_count_ == 0)
+ return -1;
+
+ // Check if multiple endpoints should be put in one profile or
+ // if they should be spread across multiple profiles.
+ if (priority == TAO_INVALID_PRIORITY)
+ return this->create_new_profile (object_key,
+ mprofile,
+ priority);
+ else
+ return this->create_shared_profile (object_key,
+ mprofile,
+ priority);
+}
+
+int
+TAO::SSLIOP::Acceptor::create_new_profile (const TAO::ObjectKey &object_key,
+ TAO_MProfile &mprofile,
+ CORBA::Short priority)
+{
+ // Adding this->endpoint_count_ to the TAO_MProfile.
+ const int count = mprofile.profile_count ();
+ if ((mprofile.size () - count) < this->endpoint_count_
+ && mprofile.grow (count + this->endpoint_count_) == -1)
+ return -1;
+
+ // Create a profile for each acceptor endpoint.
+ for (size_t i = 0; i < this->endpoint_count_; ++i)
+ {
+ TAO_SSLIOP_Profile *pfile = 0;
+
+ // @@ We need to create an SSLIOP::SSL component for the object
+ // we're creating an MProfile for. This will allow us to
+ // properly embed secure invocation policies in the generated
+ // IOR, i.e. secure invocation policies on a per-object
+ // basis, rather than on a per-endpoint basis. If no secure
+ // invocation policies have been set then we should use the
+ // below default SSLIOP::SSL component.
+ ACE_NEW_RETURN (pfile,
+ TAO_SSLIOP_Profile (this->hosts_[i],
+ this->addrs_[i].get_port_number (),
+ object_key,
+ this->addrs_[i],
+ this->version_,
+ this->orb_core_,
+ &(this->ssl_component_)),
+ -1);
+ pfile->endpoint ()->priority (priority);
+
+ if (mprofile.give_profile (pfile) == -1)
+ {
+ pfile->_decr_refcnt ();
+ pfile = 0;
+ return -1;
+ }
+
+ if (this->orb_core_->orb_params ()->std_profile_components () == 0)
+ continue;
+
+ pfile->tagged_components ().set_orb_type (TAO_ORB_TYPE);
+
+ TAO_Codeset_Manager *csm = this->orb_core_->codeset_manager();
+ if (csm)
+ csm->set_codeset (pfile->tagged_components());
+
+ IOP::TaggedComponent component;
+ component.tag = ::SSLIOP::TAG_SSL_SEC_TRANS;
+
+ // @@???? Check this code, only intended as guideline...
+ TAO_OutputCDR cdr;
+ cdr << TAO_OutputCDR::from_boolean (TAO_ENCAP_BYTE_ORDER);
+
+ // @@ We need to create an SSLIOP::SSL component for the object
+ // we're creating an MProfile for. This will allow us to
+ // properly embed secure invocation policies in the generated
+ // IOR, i.e. secure invocation policies on a per-object
+ // basis, rather than on a per-endpoint basis. If no secure
+ // invocation policies have been set then we should use the
+ // below default SSLIOP::SSL component.
+ cdr << this->ssl_component_;
+
+ // TAO extension, replace the contents of the octet sequence with
+ // the CDR stream
+ const CORBA::ULong length = cdr.total_length ();
+ component.component_data.length (length);
+ CORBA::Octet *buf = component.component_data.get_buffer ();
+ for (const ACE_Message_Block *i = cdr.begin ();
+ i != 0;
+ i = i->cont ())
+ {
+ ACE_OS::memcpy (buf, i->rd_ptr (), i->length ());
+ buf += i->length ();
+ }
+
+ pfile->tagged_components ().set_component (component);
+ }
+
+ return 0;
+}
+
+
+int
+TAO::SSLIOP::Acceptor::create_shared_profile (const TAO::ObjectKey &object_key,
+ TAO_MProfile &mprofile,
+ CORBA::Short priority)
+{
+ size_t index = 0;
+ TAO_Profile *pfile = 0;
+ TAO_SSLIOP_Profile *ssliop_profile = 0;
+
+ // First see if <mprofile> already contains a SSLIOP profile.
+ for (TAO_PHandle i = 0; i != mprofile.profile_count (); ++i)
+ {
+ pfile = mprofile.get_profile (i);
+ if (pfile->tag () == IOP::TAG_INTERNET_IOP)
+ {
+ ssliop_profile = dynamic_cast<TAO_SSLIOP_Profile *> (pfile);
+ if (ssliop_profile == 0)
+ return -1;
+ break;
+ }
+ }
+
+ // If <mprofile> doesn't contain SSLIOP_Profile, we need to create
+ // one.
+ if (ssliop_profile == 0)
+ {
+ // @@ We need to create an SSLIOP::SSL component for the object
+ // we're creating an MProfile for. This will allow us to
+ // properly embed secure invocation policies in the generated
+ // IOR, i.e. secure invocation policies on a per-object
+ // basis, rather than on a per-endpoint basis. If no secure
+ // invocation policies have been set then we should use the
+ // below default SSLIOP::SSL component.
+ ACE_NEW_RETURN (ssliop_profile,
+ TAO_SSLIOP_Profile (this->hosts_[0],
+ this->addrs_[0].get_port_number (),
+ object_key,
+ this->addrs_[0],
+ this->version_,
+ this->orb_core_,
+ &(this->ssl_component_)),
+ -1);
+
+ TAO_SSLIOP_Endpoint * const ssliop_endp =
+ dynamic_cast<TAO_SSLIOP_Endpoint *> (ssliop_profile->endpoint ());
+
+ if (!ssliop_endp)
+ return -1;
+
+ ssliop_endp->priority (priority);
+ ssliop_endp->iiop_endpoint ()->priority (priority);
+
+ if (mprofile.give_profile (ssliop_profile) == -1)
+ {
+ ssliop_profile->_decr_refcnt ();
+ ssliop_profile = 0;
+ return -1;
+ }
+
+ if (this->orb_core_->orb_params ()->std_profile_components () != 0)
+ {
+ ssliop_profile->tagged_components ().set_orb_type (TAO_ORB_TYPE);
+
+ TAO_Codeset_Manager *csm = this->orb_core_->codeset_manager();
+ if (csm)
+ csm->set_codeset(ssliop_profile->tagged_components());
+
+ IOP::TaggedComponent component;
+ component.tag = ::SSLIOP::TAG_SSL_SEC_TRANS;
+ // @@???? Check this code, only intended as guideline...
+ TAO_OutputCDR cdr;
+ cdr << TAO_OutputCDR::from_boolean (TAO_ENCAP_BYTE_ORDER);
+
+ // @@ We need to create an SSLIOP::SSL component for the
+ // object we're creating an MProfile for. This will
+ // allow us to properly embed secure invocation policies
+ // in the generated IOR, i.e. secure invocation policies
+ // on a per-object basis, rather than on a per-endpoint
+ // basis. If no secure invocation policies have been set
+ // then we should use the below default SSLIOP::SSL
+ // component.
+ cdr << this->ssl_component_;
+
+ // TAO extension, replace the contents of the octet sequence with
+ // the CDR stream
+ CORBA::ULong length = cdr.total_length ();
+ component.component_data.length (length);
+ CORBA::Octet *buf = component.component_data.get_buffer ();
+ for (const ACE_Message_Block *i = cdr.begin ();
+ i != 0;
+ i = i->cont ())
+ {
+ ACE_OS::memcpy (buf, i->rd_ptr (), i->length ());
+ buf += i->length ();
+ }
+
+ ssliop_profile->tagged_components ().set_component (component);
+ }
+
+ index = 1;
+ }
+
+ // Add any remaining endpoints to the SSLIOP_Profile.
+ for (;
+ index < this->endpoint_count_;
+ ++index)
+ {
+ TAO_SSLIOP_Endpoint *ssl_endp = 0;
+ TAO_IIOP_Endpoint *iiop_endp = 0;
+ ACE_NEW_RETURN (iiop_endp,
+ TAO_IIOP_Endpoint (this->hosts_[index],
+ this->addrs_[index].get_port_number (),
+ this->addrs_[index]),
+ -1);
+ iiop_endp->priority (priority);
+
+ ACE_NEW_RETURN (ssl_endp,
+ TAO_SSLIOP_Endpoint (&(this->ssl_component_),
+ iiop_endp),
+ -1);
+
+ ssl_endp->priority (priority);
+ ssliop_profile->add_endpoint (ssl_endp);
+ }
+
+ return 0;
+}
+
+int
+TAO::SSLIOP::Acceptor::is_collocated (const TAO_Endpoint *endpoint)
+{
+ const TAO_SSLIOP_Endpoint *endp =
+ dynamic_cast<const TAO_SSLIOP_Endpoint *> (endpoint);
+
+ // Make sure the dynamically cast pointer is valid.
+ if (endp == 0)
+ return 0;
+
+ for (size_t i = 0; i < this->endpoint_count_; ++i)
+ {
+ // @@ TODO The following code looks funky, why only the address
+ // is compared? What about the IIOP address? Why force a
+ // DNS lookup every time an SSLIOP object is decoded:
+ //
+ // http://deuce.doc.wustl.edu/bugzilla/show_bug.cgi?id=1220
+ //
+ if (endp->iiop_endpoint ()->object_addr () == this->addrs_[i])
+ return 1; // Collocated
+ }
+
+ return 0; // Not collocated
+}
+
+int
+TAO::SSLIOP::Acceptor::close (void)
+{
+ int r = this->ssl_acceptor_.close ();
+ if (this->IIOP_SSL_Acceptor::close () != 0)
+ r = -1;
+
+ return r;
+}
+
+int
+TAO::SSLIOP::Acceptor::open (TAO_ORB_Core *orb_core,
+ ACE_Reactor *reactor,
+ int major,
+ int minor,
+ const char *address,
+ const char *options)
+{
+ // Ensure that neither the endpoint configuration nor the ORB
+ // configuration violate security measures.
+ if (this->verify_secure_configuration (orb_core,
+ major,
+ minor) != 0)
+ return -1;
+
+ ACE_INET_Addr addr;
+ ACE_CString specified_hostname;
+ if (this->parse_address (address, addr, specified_hostname) == -1)
+ return -1;
+
+ // Open the non-SSL enabled endpoints, then open the SSL enabled
+ // endpoints.
+ if (this->IIOP_SSL_Acceptor::open (orb_core,
+ reactor,
+ major,
+ minor,
+ address,
+ options) != 0)
+ return -1;
+
+ // The SSL port is set in the parse_options() method. All we have
+ // to do is call open_i()
+ addr.set_port_number (this->ssl_component_.port);
+
+ return this->ssliop_open_i (orb_core,
+ addr,
+ reactor);
+}
+
+int
+TAO::SSLIOP::Acceptor::open_default (TAO_ORB_Core *orb_core,
+ ACE_Reactor *reactor,
+ int major,
+ int minor,
+ const char *options)
+{
+ // Ensure that neither the endpoint configuration nor the ORB
+ // configuration violate security measures.
+ if (this->verify_secure_configuration (orb_core,
+ major,
+ minor) != 0)
+ return -1;
+
+ // Open the non-SSL enabled endpoints, then open the SSL enabled
+ // endpoints.
+ if (this->IIOP_SSL_Acceptor::open_default (orb_core,
+ reactor,
+ major,
+ minor,
+ options) == -1)
+ return -1;
+
+ // Now that each network interface's hostname has been cached, open
+ // an endpoint on each network interface using the INADDR_ANY
+ // address.
+ ACE_INET_Addr addr;
+
+ // this->ssl_component_.port is initialized to zero or it is set in
+ // this->parse_options().
+ if (addr.set (this->ssl_component_.port,
+ static_cast<ACE_UINT32> (INADDR_ANY),
+ 1) != 0)
+ return -1;
+
+ return this->ssliop_open_i (orb_core,
+ addr,
+ reactor);
+}
+
+int
+TAO::SSLIOP::Acceptor::ssliop_open_i (TAO_ORB_Core *orb_core,
+ const ACE_INET_Addr& addr,
+ ACE_Reactor *reactor)
+{
+ this->orb_core_ = orb_core;
+
+ // Explicitly disable GIOPlite support since it introduces security
+ // holes.
+ static const int giop_lite = 0;
+
+ ACE_NEW_RETURN (this->creation_strategy_,
+ CREATION_STRATEGY (this->orb_core_,
+ giop_lite),
+ -1);
+
+ ACE_NEW_RETURN (this->concurrency_strategy_,
+ CONCURRENCY_STRATEGY (this->orb_core_),
+ -1);
+
+ ACE_NEW_RETURN (this->accept_strategy_,
+ ACCEPT_STRATEGY (this->orb_core_,
+ this->timeout_),
+ -1);
+
+ u_short requested_port = addr.get_port_number ();
+ if (requested_port == 0)
+ {
+ // don't care, i.e., let the OS choose an ephemeral port
+ if (this->ssl_acceptor_.open (addr,
+ reactor,
+ this->creation_strategy_,
+ this->accept_strategy_,
+ this->concurrency_strategy_,
+ 0, 0, 0, 1,
+ this->reuse_addr_) == -1)
+ {
+ if (TAO_debug_level > 0)
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("\n\nTAO (%P|%t) ")
+ ACE_TEXT ("SSLIOP_Acceptor::open_i - %p\n\n"),
+ ACE_TEXT ("cannot open acceptor")));
+ return -1;
+ }
+ }
+ else
+ {
+ ACE_INET_Addr a(addr);
+
+ int found_a_port = 0;
+ ACE_UINT32 last_port = requested_port + this->port_span_ - 1;
+ if (last_port > ACE_MAX_DEFAULT_PORT)
+ {
+ last_port = ACE_MAX_DEFAULT_PORT;
+ }
+
+ for (ACE_UINT32 p = requested_port; p <= last_port; p++)
+ {
+ if (TAO_debug_level > 5)
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) IIOP_Acceptor::open_i() ")
+ ACE_TEXT ("trying to listen on port %d\n"), p));
+
+ // Now try to actually open on that port
+ a.set_port_number ((u_short)p);
+ if (this->ssl_acceptor_.open (a,
+ reactor,
+ this->creation_strategy_,
+ this->accept_strategy_,
+ this->concurrency_strategy_,
+ 0, 0, 0, 1,
+ this->reuse_addr_) != -1)
+ {
+ found_a_port = 1;
+ break;
+ }
+ }
+
+ // Now, if we couldn't locate a port, we punt
+ if (! found_a_port)
+ {
+ if (TAO_debug_level > 0)
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("\n\nTAO (%P|%t) ")
+ ACE_TEXT ("SSLIOP_Acceptor::open_i - %p\n\n"),
+ ACE_TEXT ("cannot open acceptor")));
+ return -1;
+ }
+ }
+
+ ACE_INET_Addr ssl_address;
+
+ // We do this to make sure the port number the endpoint is listening
+ // on gets set in the addr.
+ if (this->ssl_acceptor_.acceptor ().get_local_addr (ssl_address) != 0)
+ {
+ // @@ Should this be a catastrophic error???
+ if (TAO_debug_level > 0)
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("\n\nTAO (%P|%t) ")
+ ACE_TEXT ("SSLIOP_Acceptor::open_i - %p\n\n"),
+ ACE_TEXT ("cannot get local addr")));
+ return -1;
+ }
+
+ // Reset the SSL endpoint port to the one chosen by the OS (or by
+ // the user if provided.
+ this->ssl_component_.port = ssl_address.get_port_number ();
+
+ (void) this->ssl_acceptor_.acceptor().enable (ACE_CLOEXEC);
+ // This avoids having child processes acquire the listen socket
+ // thereby denying the server the opportunity to restart on a
+ // well-known endpoint. This does not affect the aberrent behavior
+ // on Win32 platforms.
+
+ if (TAO_debug_level > 5)
+ {
+ for (size_t i = 0; i < this->endpoint_count_; ++i)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) ")
+ ACE_TEXT ("SSLIOP_Acceptor::open_i - ")
+ ACE_TEXT ("listening on: <%s:%u>\n"),
+ this->hosts_[i],
+ this->ssl_component_.port));
+ }
+ }
+
+ return 0;
+}
+
+int
+TAO::SSLIOP::Acceptor::parse_options_i (int &argc, ACE_CString ** argv)
+{
+ //first, do the base class parser, then parse the leftovers.
+ int result = this->IIOP_SSL_Acceptor::parse_options_i(argc,argv);
+ if (result == -1)
+ return result;
+
+ // then parse out our own options.
+ int i = 0;
+ while (i < argc)
+ {
+ // since the base class has already iterated over the list once,
+ // it has vound any ill-formed options. Therefore we don't need
+ // to do that again here.
+ int slot = argv[i]->find ("=");
+ ACE_CString name = argv[i]->substring (0, slot);
+ ACE_CString value = argv[i]->substring (slot + 1);
+
+ if (name == "priority")
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("TAO (%P|%t) Invalid SSLIOP endpoint format: ")
+ ACE_TEXT ("endpoint priorities no longer supported. \n"),
+ value.c_str ()),
+ -1);
+ }
+ else if (ACE_OS::strcmp (name.c_str (), "ssl_port") == 0)
+ {
+ int ssl_port = ACE_OS::atoi (value.c_str ());
+
+ if (ssl_port >= 0 && ssl_port < 65536)
+ this->ssl_component_.port = ssl_port;
+ else
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("TAO (%P|%t) Invalid ")
+ ACE_TEXT ("IIOP/SSL endpoint ")
+ ACE_TEXT ("port: <%s>\n"),
+ value.c_str ()),
+ -1);
+ }
+ else
+ {
+ // the name is not known, skip to the next option
+ i++;
+ continue;
+ }
+ // at the end, we've consumed this argument. Shift the list and
+ // put this one on the end. This technique has the effect of
+ // putting them in reverse order, but that doesn't matter, since
+ // these arguments are only whole strings.
+ argc--;
+ ACE_CString *temp = argv[i];
+ for (int j = i; j <= argc-1; j++)
+ argv[j] = argv[j+1];
+ argv[argc] = temp;
+
+ }
+ return 0;
+}
+
+int
+TAO::SSLIOP::Acceptor::verify_secure_configuration (TAO_ORB_Core *orb_core,
+ int major,
+ int minor)
+{
+ // Sanity check.
+ if (major < 1)
+ {
+ // There is no such thing as IIOP 0.x.
+ errno = EINVAL;
+ return -1;
+ }
+
+ // In order to support a secure connection, the SSLIOP::SSL tagged
+ // component must be embedded in the IOR. This isn't possible if
+ // the user elects to disable standard profile components.
+ // Similarly, IIOP 1.0 does not support tagged components, which
+ // makes it impossible to embed the SSLIOP::SSL tagged component
+ // within the IOR. If the given object explicitly disallows
+ // insecure invocations and standard profile components are
+ // disabled, then return with an error since secure invocations
+ // cannot be supported without standard profile components.
+ //
+ // Note that it isn't enough to support NoProtection. NoProtection
+ // must be required since "support" does not preclude the secure
+ // port from being used.
+
+ if ((orb_core->orb_params ()->std_profile_components () == 0
+ || (major == 1 && minor == 0))
+ && ACE_BIT_DISABLED (this->ssl_component_.target_requires,
+ ::Security::NoProtection))
+ {
+ if (TAO_debug_level > 0)
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) Cannot support secure ")
+ ACE_TEXT ("IIOP over SSL connection if\n")
+ ACE_TEXT ("(%P|%t) standard profile ")
+ ACE_TEXT ("components are disabled\n")
+ ACE_TEXT ("(%P|%t) or IIOP 1.0 endpoint is ")
+ ACE_TEXT ("used.\n")));
+
+ errno = EINVAL;
+ return -1;
+ }
+
+ return 0;
+}
+
+TAO_END_VERSIONED_NAMESPACE_DECL