diff options
46 files changed, 2130 insertions, 150 deletions
diff --git a/TAO/ChangeLog b/TAO/ChangeLog index 140dd148a1b..aa32a4b86bc 100644 --- a/TAO/ChangeLog +++ b/TAO/ChangeLog @@ -1,3 +1,95 @@ +Thu Jul 12 16:51:30 UTC 2007 Phil Mesnier <mesnier_p@ociweb.com> + + * orbsvcs/orbsvcs/SSLIOP/SSLIOP_Connector.cpp: + * orbsvcs/orbsvcs/SSLIOP/SSLIOP_Invocation_Interceptor.h: + * orbsvcs/orbsvcs/SSLIOP/SSLIOP_Invocation_Interceptor.cpp: + * orbsvcs/orbsvcs/SSLIOP/SSLIOP_ORBInitializer.cpp: + * orbsvcs/orbsvcs/Security/SL2_SecurityManager.h: + * orbsvcs/orbsvcs/Security/SL2_SecurityManager.cpp: + * orbsvcs/orbsvcs/Security/Security_ORBInitializer.cpp: + The mixed security feature is an implementation of the Security + Level 2 Access Decision interface. The actual implementation + deviates slightly from the specification because the spec + requires passing an object reference for the target to be + considered by the access_allowed operation. Unfortunately the + point where this method is called requires synthesizing an + object reference based on a POA and an object ID. But doing this + requires the POA to have the RETAIN policy set otherwise + id_to_reference fails. Furthermore, there is no way to + conclusively compare two object references. The obvious way, + calling object_to_string() and comparing the results fails + because the stringified reference is really a CDR buffer that + contains alignment padding bytes that are filled with garbage. + Two otherwise identical references might have different strings. + To work around these problems, we implement an alternative + interface to take ORB, POA, and object ids as blobs and use + these for comparisons. + + * orbsvcs/orbsvcs/SecurityLevel2.idl: + * orbsvcs/tests/Security/mixed_security_test: + * orbsvcs/tests/Security/mixed_security_test/Foo.idl: + * orbsvcs/tests/Security/mixed_security_test/Foo_i.h: + * orbsvcs/tests/Security/mixed_security_test/Foo_i.cpp: + * orbsvcs/tests/Security/mixed_security_test/README: + * orbsvcs/tests/Security/mixed_security_test/cacert.pem: + * orbsvcs/tests/Security/mixed_security_test/client.conf: + * orbsvcs/tests/Security/mixed_security_test/client.conf.xml: + * orbsvcs/tests/Security/mixed_security_test/client.cpp: + * orbsvcs/tests/Security/mixed_security_test/client_cert.pem: + * orbsvcs/tests/Security/mixed_security_test/client_key.pem: + * orbsvcs/tests/Security/mixed_security_test/client_key_nopasswd.pem: + * orbsvcs/tests/Security/mixed_security_test/client_none.conf: + * orbsvcs/tests/Security/mixed_security_test/client_nopasswd.conf: + * orbsvcs/tests/Security/mixed_security_test/client_nopasswd.conf.xml: + * orbsvcs/tests/Security/mixed_security_test/constants.h: + * orbsvcs/tests/Security/mixed_security_test/mixed_security.mpc: + * orbsvcs/tests/Security/mixed_security_test/run_test.pl: + * orbsvcs/tests/Security/mixed_security_test/server.conf: + * orbsvcs/tests/Security/mixed_security_test/server.conf.xml: + * orbsvcs/tests/Security/mixed_security_test/server.cpp: + * orbsvcs/tests/Security/mixed_security_test/server_cert.pem: + * orbsvcs/tests/Security/mixed_security_test/server_key.pem: + * orbsvcs/tests/Security/mixed_security_test/server_key_nopasswd.pem: + * orbsvcs/tests/Security/mixed_security_test/server_none.conf: + * orbsvcs/tests/Security/mixed_security_test/server_none.conf.xml: + * orbsvcs/tests/Security/mixed_security_test/server_nopasswd.conf: + * orbsvcs/tests/Security/mixed_security_test/server_nopasswd.conf.xml: + This is the regression test for validating the mixed security + feature. + + * tao/CDR.cpp: + * tao/Profile.cpp: + During the development of the mixed security feature, it was + discovered that comparing object references by comparing + stringified buffers failed because the stringified buffers + contained alignment padding bytes that contained garbage. This + garbage is ignored by CDR, but causes two otherwise identical + object references to fail to compare. As a way to validate this + problem we added some code to initialize a CDR buffer to all + zeros before encoding to it, thereby ensuring that twe encodings + of the same object reference would yield the same stringified + result. The mixed security feature was reimplemented to not + require a full object reference for comparison anyway, rending + this problem moot for the moment. The buffer blanking code is + left in place, but not compiled. + + * tests/objref_comparison_test/foo.idl: + * tests/objref_comparison_test/main.cpp: + * tests/objref_comparison_test/objref_comparison_test.mpc: + * tests/objref_comparison_test/server.conf: + * tests/objref_comparison_test/server_cert.pem: + * tests/objref_comparison_test/server_key.pem: + This test is used to highlight the difficulty in comparing + object references. It is not to be added to the nightly build + suite. + + * utils/catior/catior.cpp: + Add the ability to parse out ssl component elements. This does + not require linking any ssl or SSLIOP code. + + * orbsvcs/Naming_Service/NT_Naming_Server.cpp: + Fix emacs mode selector line. + Thu Jul 12 11:29:39 UTC 2007 Vadym Ridosh <vridosh@prismtech.com> * tao/Strategies/DIOP_Connector.cpp: @@ -26,21 +118,21 @@ Thu Jul 12 11:29:39 UTC 2007 Vadym Ridosh <vridosh@prismtech.com> Made that shutdown is called 10 times in all DIOP tests to make sure that server does not miss it. Added scripts for testing IPv6 implementation in DIOP. - + Thu Jul 12 09:39:46 UTC 2007 Jeff Parsons <j.parsons@vanderbilt.edu> * orbsvcs/orbsvcs/IFRService/UnionDef_i.h: - + Cosmetic changes. - + * orbsvcs/orbsvcs/IFRService/Container_i.cpp(create_union_i): - + Added check for a null discriminator type before setting a reference to it in the repository. Required to support creation of an entry for a forward declared union, in which case the discriminator and the members will be added when the full definition is seen. - + * orbsvcs/IFR_Service/ifr_adding_visitor.h: * orbsvcs/IFR_Service/ifr_adding_visitor_union.h: * orbsvcs/IFR_Service/ifr_adding_visitor_exception.h: @@ -49,7 +141,7 @@ Thu Jul 12 09:39:46 UTC 2007 Jeff Parsons <j.parsons@vanderbilt.edu> * orbsvcs/IFR_Service/ifr_adding_visitor_union.cpp: * orbsvcs/IFR_Service/ifr_adding_visitor_exception.cpp: * orbsvcs/IFR_Service/ifr_adding_visitor_structure.cpp: - + - Added support for forward declared structs and unions. - Factored out common code that adds union members, used when creating a new union entry in the repo and also @@ -57,18 +149,18 @@ Thu Jul 12 09:39:46 UTC 2007 Jeff Parsons <j.parsons@vanderbilt.edu> created for a forward delared union. - Added changes required by changes in the TAO_IDL front end for typedefs. - + * tao/AnyTypeCode/TypeCode_Case_Enum_T.cpp: - + Changed code that compares equality of union labels where the discriminator is an enum to always extract the value to compare as an unsigned long, since the Any extraction operator overload for the enum type may not be known to the ORB code that is doing the comparison. - + * tao/TypeCodeFactory/TypeCodeFactory_i.h(check_recursion): * tao/TypeCodeFactory/TypeCodeFactory_i.cpp(check_recursion): - + Added parameter to the method that holds a 'working id' that enables the method to determine that, although a recursion has been detected, it may be the recursion of diff --git a/TAO/orbsvcs/Naming_Service/NT_Naming_Server.cpp b/TAO/orbsvcs/Naming_Service/NT_Naming_Server.cpp index d510360f1a2..f8533a74e85 100644 --- a/TAO/orbsvcs/Naming_Service/NT_Naming_Server.cpp +++ b/TAO/orbsvcs/Naming_Service/NT_Naming_Server.cpp @@ -1,4 +1,4 @@ -// *- C++ -*- +// -*- C++ -*- // $Id$ // ============================================================================ diff --git a/TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_Connector.cpp b/TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_Connector.cpp index a1bd7d9b1ec..c192d1b8066 100644 --- a/TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_Connector.cpp +++ b/TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_Connector.cpp @@ -348,6 +348,7 @@ TAO::SSLIOP::Connector::iiop_connect ( TAO::Profile_Transport_Resolver *resolver, ACE_Time_Value *timeout) { +#if 0 const ::SSLIOP::SSL &ssl_component = ssl_endpoint->ssl_component (); // Only allow connection to the insecure IIOP port if the endpoint @@ -368,6 +369,7 @@ TAO::SSLIOP::Connector::iiop_connect ( TAO::VMCID, EPERM), CORBA::COMPLETED_NO); +#endif TAO_IIOP_Endpoint *iiop_endpoint = ssl_endpoint->iiop_endpoint (); diff --git a/TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_Invocation_Interceptor.cpp b/TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_Invocation_Interceptor.cpp index f1542176fa3..ddcf5182e5e 100644 --- a/TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_Invocation_Interceptor.cpp +++ b/TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_Invocation_Interceptor.cpp @@ -1,9 +1,11 @@ #include "orbsvcs/SSLIOP/SSLIOP_Invocation_Interceptor.h" +#include "orbsvcs/SSLIOP/SSLIOP_Current.h" #include "orbsvcs/SecurityLevel2C.h" #include "tao/ORB_Constants.h" #include "tao/PortableServer/PS_CurrentC.h" +#include "tao/PortableServer/POAC.h" #include "tao/debug.h" #if defined (SSLIOP_DEBUG_PEER_CERTIFICATE) @@ -17,12 +19,54 @@ ACE_RCSID (SSLIOP, TAO_BEGIN_VERSIONED_NAMESPACE_DECL -TAO::SSLIOP::Server_Invocation_Interceptor::Server_Invocation_Interceptor ( - ::SSLIOP::Current_ptr current, - ::Security::QOP qop) - : ssliop_current_ (::SSLIOP::Current::_duplicate (current)), - qop_ (qop) +TAO::SSLIOP::Server_Invocation_Interceptor::Server_Invocation_Interceptor +( + PortableInterceptor::ORBInitInfo_ptr info, + ::Security::QOP default_qop, + size_t tss_slot +) +: qop_ (default_qop) { + /* + * Cache references to the "Current" objects that we'll need during + * during invocations. + */ + + CORBA::Object_var obj = + info->resolve_initial_references ("SSLIOPCurrent"); + + this->ssliop_current_ = ::SSLIOP::Current::_narrow (obj.in ()); + + if (!CORBA::is_nil (this->ssliop_current_.in ())) + { + TAO::SSLIOP::Current *tao_current = + dynamic_cast<TAO::SSLIOP::Current *> (this->ssliop_current_.in ()); + + if (tao_current != 0) + { + if (TAO_debug_level > 3) + ACE_DEBUG ((LM_DEBUG, "TAO (%P|%t) SSLIOP_Invocation_Interceptor::CTOR--setting up SSLIOP Current with slot %d\n", tss_slot)); + tao_current->tss_slot (tss_slot); + } + else + throw CORBA::INTERNAL (); + } + + obj = info->resolve_initial_references ("SecurityLevel2:SecurityManager"); + this->sec2manager_ = SecurityLevel2::SecurityManager::_narrow (obj.in ()); + + if (! CORBA::is_nil (this->sec2manager_.in ())) + { + // set the slot id? things seem to work without doing this + } + +#if 0 + // Don't need this now that we're not using access_allowed(), but + // I'm leaving the code here just in case it would become convenient + // for some other use. + obj = info->resolve_initial_references ("POACurrent"); + this->poa_current_ = PortableServer::Current::_narrow (obj.in ()); +#endif } TAO::SSLIOP::Server_Invocation_Interceptor::~Server_Invocation_Interceptor ( @@ -45,93 +89,84 @@ void TAO::SSLIOP::Server_Invocation_Interceptor::receive_request_service_contexts ( PortableInterceptor::ServerRequestInfo_ptr /*ri*/) { - // The current upcall is not being performed through an SSL - // connection. If server is configured to disallow insecure - // invocations then throw a CORBA::NO_PERMISSION exception. - // @@ TODO: Once the SecurityManager is implemented, query it - // for the current object's - // SecureInvocationPolicy of type - // SecTargetSecureInvocationPolicy so that we can - // accept or reject requests on a per-object basis - // instead on a per-endpoint basis. - CORBA::Boolean const no_ssl = this->ssliop_current_->no_context (); - - if (TAO_debug_level >= 3) - ACE_DEBUG ((LM_DEBUG, "SSLIOP (%P|%t) Interceptor (context), ssl=%d\n", !(no_ssl))); - - if (no_ssl && this->qop_ != ::Security::SecQOPNoProtection) - throw CORBA::NO_PERMISSION (); - -#if defined(SSLIOP_DEBUG_PEER_CERTIFICATE) - try - { - // If the request was not made through an SSL connection, then - // this method will throw the SSLIOP::Current::NoContext - // exception. Otherwise, it will return a DER encoded X509 - // certificate. - ::SSLIOP::ASN_1_Cert_var cert = - this->ssliop_current_->get_peer_certificate (); - - // @@ The following debugging code works but I don't think that - // we should include it since it dumps alot of information, - // i.e. prints two lines of information per request. - if (TAO_debug_level > 1) - { - const CORBA::Octet *der_cert = cert->get_buffer (); - - ::X509 *peer = ::d2i_X509 (0, &der_cert, cert->length ()); - if (peer != 0) - { - char buf[BUFSIZ] = { 0 }; - - ::X509_NAME_oneline (::X509_get_subject_name (peer), - buf, - BUFSIZ); +} - ACE_DEBUG ((LM_DEBUG, - "(%P|%t) Certificate subject: %s\n", - buf)); - ::X509_NAME_oneline (::X509_get_issuer_name (peer), - buf, - BUFSIZ); +void +TAO::SSLIOP::Server_Invocation_Interceptor::receive_request ( + PortableInterceptor::ServerRequestInfo_ptr ri ) +{ + SecurityLevel2::AccessDecision_var ad_tmp = + this->sec2manager_->access_decision (); + TAO::SL2::AccessDecision_var ad = + TAO::SL2::AccessDecision::_narrow (ad_tmp.in ()); - ACE_DEBUG ((LM_DEBUG, - "(%P|%t) Certificate issuer: %s\n", - buf)); + CORBA::Boolean const no_ssl = + this->ssliop_current_->no_context (); + if (TAO_debug_level >= 3) + ACE_DEBUG ((LM_DEBUG, "SSLIOP (%P|%t) Interceptor (context), ssl=%d\n", !(no_ssl))); - ::X509_free (peer); - } - else - { - ACE_DEBUG ((LM_DEBUG, - "(%P|%t) No certificate info\n")); - } - } - } - catch (const ::SSLIOP::Current::NoContext& ) + // if + // (1) no SSL session state is available (which means that the + // invocation is received across a non-SSL transport) + // AND + // (2) the required Quality of Protection is something other + // than SecQOPNoProtection (set via -SSLNoProtection) + if (no_ssl && this->qop_ != ::Security::SecQOPNoProtection) { - // The current upcall is not being performed through an SSL - // connection. If server is configured to disallow insecure - // invocations then throw a CORBA::NO_PERMISSION exception. - // @@ TODO: Once the SecurityManager is implemented, query it - // for the current object's - // SecureInvocationPolicy of type - // SecTargetSecureInvocationPolicy so that we can - // accept or reject requests on a per-object basis - // instead on a per-endpoint basis. - if (this->qop_ != ::Security::SecQOPNoProtection) - throw CORBA::NO_PERMISSION (); + /* + * Set up all the arguments needed by the call + * to AccessDecision::access_allowed() + */ + + /* Get the credentials from SSLIOP */ + SecurityLevel2::CredentialsList cred_list; // initial empty? +#if 0 + try { + SecurityLevel2::ReceivedCredentials_var rcvd_creds = + this->sec2_current_->received_credentials (); + // this gets the credentials received from the other side. We + // should be able to put this into a CredentialsList with no + // problem. + // + // Do I really need to implement a sec2_current, or can I hack + // the conversion at this level? I probably ought to do it as + // a real sec2_current with the conversion from sec3->sec2 + // happening at a lower level. + + cred_list.length(1); + cred_list[0] = rcvd_creds.in (); + /* + So, in looking for how we can do this, I find that the + SL3_SecurityCurrent::client_credentials() delegates to SL3_SecurityCurrent_Impl::client_credentials(), which is pure virtual. + */ + } + catch (...) { + } +#endif + + /* Gather the elements that uniquely identify the target object */ + CORBA::ORBid_var orb_id = ri->orb_id (); + CORBA::OctetSeq_var adapter_id = ri->adapter_id (); + CORBA::OctetSeq_var object_id = ri->object_id (); + + CORBA::String_var operation_name = ri->operation (); + + CORBA::Boolean it_should_happen = false; + it_should_happen = ad->access_allowed_ex (orb_id.in (), + adapter_id.in (), + object_id.in (), + cred_list, + operation_name.in()); + if (TAO_debug_level >= 3) + ACE_DEBUG ((LM_DEBUG, + "TAO (%P|%t) SL2::access_allowed_ex returned %s\n", + it_should_happen ? "true" : "false")); + + if (! it_should_happen) + throw CORBA::NO_PERMISSION (); } -#endif /* SSLIOP_DEBUG_PEER_CERTIFICATE */ -} - - -void -TAO::SSLIOP::Server_Invocation_Interceptor::receive_request ( - PortableInterceptor::ServerRequestInfo_ptr /* ri */) -{ } void diff --git a/TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_Invocation_Interceptor.h b/TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_Invocation_Interceptor.h index af09c09b702..9375c18ac2d 100644 --- a/TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_Invocation_Interceptor.h +++ b/TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_Invocation_Interceptor.h @@ -22,8 +22,11 @@ #endif /* ACE_LACKS_PRAGMA_ONCE */ #include "orbsvcs/SSLIOPC.h" +#include "orbsvcs/SecurityLevel2C.h" #include "tao/PortableInterceptorC.h" +#include "tao/PI/ORBInitInfo.h" #include "tao/PI_Server/PI_Server.h" +#include "tao/PortableServer/PS_CurrentC.h" #include "tao/LocalObject.h" // This is to remove "inherits via dominance" warnings from MSVC. @@ -55,9 +58,16 @@ namespace TAO { public: - /// Constructor. - Server_Invocation_Interceptor (::SSLIOP::Current_ptr current, - ::Security::QOP qop); + /*! + \brief Constructor. + \param info reference to the ORBInitInfo object so that + the interceptor can get access to initial references, etc. + \param default_qop the default Quality of Protection + \param tss_slot the TSS slot used by the various security features. + */ + Server_Invocation_Interceptor (PortableInterceptor::ORBInitInfo_ptr info, + ::Security::QOP default_qop, + size_t tss_slot); /** * @name PortableInterceptor::ServerRequestInterceptor Methods @@ -113,9 +123,15 @@ namespace TAO /// Reference to the current SSLIOP execution context. ::SSLIOP::Current_var ssliop_current_; + /// Reference to the POA current + PortableServer::Current_var poa_current_; + /// The default quality-of-protection settings in use. ::Security::QOP qop_; + /// SecurityLevel2 security manager reference + SecurityLevel2::SecurityManager_var sec2manager_; + SecurityLevel2::Current_var sec2_current_; }; } // End SSLIOP namespace. diff --git a/TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_ORBInitializer.cpp b/TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_ORBInitializer.cpp index c5d7846cb29..d0e0e91d04e 100644 --- a/TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_ORBInitializer.cpp +++ b/TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_ORBInitializer.cpp @@ -84,34 +84,14 @@ TAO::SSLIOP::ORBInitializer::post_init ( // object is registered for each ORB in this ORBInitializer's // pre_init() method. - CORBA::Object_var obj = - info->resolve_initial_references ("SSLIOPCurrent"); - - SSLIOP::Current_var ssliop_current = - SSLIOP::Current::_narrow (obj.in ()); - - if (!CORBA::is_nil (ssliop_current.in ())) - { - TAO::SSLIOP::Current *tao_current = - dynamic_cast<TAO::SSLIOP::Current *> (ssliop_current.in ()); - - if (tao_current != 0) - { - size_t const slot = this->get_tss_slot_id (info); - - tao_current->tss_slot (slot); - } - else - throw CORBA::INTERNAL (); - } - // Create the SSLIOP secure invocation server request interceptor. PortableInterceptor::ServerRequestInterceptor_ptr si = PortableInterceptor::ServerRequestInterceptor::_nil (); ACE_NEW_THROW_EX (si, - TAO::SSLIOP::Server_Invocation_Interceptor ( - ssliop_current.in (), - this->qop_), + TAO::SSLIOP::Server_Invocation_Interceptor + (info, + this->qop_, + this->get_tss_slot_id (info)), CORBA::NO_MEMORY ( CORBA::SystemException::_tao_minor_code ( TAO::VMCID, @@ -156,7 +136,8 @@ TAO::SSLIOP::ORBInitializer::post_init ( // Register the SSLIOP-specific vault with the // PrincipalAuthenticator. - obj = info->resolve_initial_references ("SecurityLevel3:SecurityManager"); + CORBA::Object_var obj = + info->resolve_initial_references ("SecurityLevel3:SecurityManager"); SecurityLevel3::SecurityManager_var manager = SecurityLevel3::SecurityManager::_narrow (obj.in ()); diff --git a/TAO/orbsvcs/orbsvcs/Security/SL2_SecurityManager.cpp b/TAO/orbsvcs/orbsvcs/Security/SL2_SecurityManager.cpp new file mode 100644 index 00000000000..8e7b22c66d1 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Security/SL2_SecurityManager.cpp @@ -0,0 +1,325 @@ +// $Id$ + +#include "orbsvcs/Security/SL2_SecurityManager.h" + +#include "tao/ORB_Constants.h" +#include "ace/Functor.h" +#include "tao/Object_KeyC.h" +#include "tao/PortableServer/Root_POA.h" +#include "tao/PortableServer/Object_Adapter.h" +#include "tao/PortableServer/Creation_Time.h" + +ACE_RCSID (Security, + SL2_SecurityManager, + "$Id$") + + +TAO_BEGIN_VERSIONED_NAMESPACE_DECL + +TAO::Security::SecurityManager::SecurityManager (/* unknown */) + : principal_authenticator_ (SecurityLevel2::PrincipalAuthenticator::_nil ()) +{ + // this needs to change to access decision + SecurityLevel2::AccessDecision_ptr ad; + ACE_NEW_THROW_EX (ad, + TAO::Security::AccessDecision, + CORBA::NO_MEMORY ( + CORBA::SystemException::_tao_minor_code ( + TAO::VMCID, + ENOMEM), + CORBA::COMPLETED_NO)); + + this->access_decision_ = ad; +} + +TAO::Security::SecurityManager::~SecurityManager (void) +{ +} + +Security::MechandOptionsList* +TAO::Security::SecurityManager::supported_mechanisms () +{ + throw CORBA::NO_IMPLEMENT (); +} + +SecurityLevel2::CredentialsList* +TAO::Security::SecurityManager::own_credentials () +{ + throw CORBA::NO_IMPLEMENT (); +} + +SecurityLevel2::RequiredRights_ptr +TAO::Security::SecurityManager::required_rights_object () +{ + throw CORBA::NO_IMPLEMENT (); +} + +SecurityLevel2::PrincipalAuthenticator_ptr +TAO::Security::SecurityManager::principal_authenticator () +{ + return SecurityLevel2::PrincipalAuthenticator::_duplicate + (this->principal_authenticator_.in () ); +} + +SecurityLevel2::AccessDecision_ptr +TAO::Security::SecurityManager::access_decision () +{ + return SecurityLevel2::AccessDecision::_duplicate (this->access_decision_.in () ); +} + +SecurityLevel2::AuditDecision_ptr +TAO::Security::SecurityManager::audit_decision () +{ + throw CORBA::NO_IMPLEMENT (); +} + +SecurityLevel2::TargetCredentials_ptr +TAO::Security::SecurityManager::get_target_credentials (CORBA::Object_ptr /*o*/) +{ + throw CORBA::NO_IMPLEMENT (); +} + +void +TAO::Security::SecurityManager::remove_own_credentials + (SecurityLevel2::Credentials_ptr /*creds*/) +{ + throw CORBA::NO_IMPLEMENT (); +} + +CORBA::Policy_ptr +TAO::Security::SecurityManager::get_security_policy +(CORBA::PolicyType /*policy_type */) +{ + throw CORBA::NO_IMPLEMENT (); +} + +/* + * AccessDecision stuff below here + */ + +bool +TAO::Security::AccessDecision::ReferenceKeyType::operator== + (const ReferenceKeyType& other) const +{ + ::CORBA::ULong olen = this->oid_->length(); + ::CORBA::ULong alen = this->adapter_id_->length(); + + if (olen == other.oid_->length() && + alen == other.adapter_id_->length()) + return (ACE_OS::memcmp (this->oid_->get_buffer(), + other.oid_->get_buffer(),olen) == 0 && + ACE_OS::memcmp (this->adapter_id_->get_buffer(), + other.adapter_id_->get_buffer(),alen) == 0 && + ACE_OS_String::strcmp (this->orbid_.in(), other.orbid_.in()) == 0); + return false; +} + +CORBA::ULong +TAO::Security::AccessDecision::ReferenceKeyType::hash () const +{ + return 0; +} + +TAO::Security::AccessDecision::ReferenceKeyType::operator const char* () const +{ + return "<hardcoded refkey>"; +} + +TAO::Security::AccessDecision::AccessDecision () + : default_allowance_decision_ (false) +{ +} + +TAO::Security::AccessDecision::~AccessDecision () +{ +} + +TAO::Security::AccessDecision::OBJECT_KEY +TAO::Security::AccessDecision::map_key_from_objref (CORBA::Object_ptr /*obj */) +{ + ACE_ERROR ((LM_ERROR,"map_key_from_objref is currently not implemented\n")); + throw CORBA::NO_IMPLEMENT(); + + OBJECT_KEY key; + return key; +} + +CORBA::Boolean +TAO::Security::AccessDecision::access_allowed_i (OBJECT_KEY &key, + const char *operation_name) +{ + // LOCK THE MAP! + ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, guard, this->map_lock_, + this->default_allowance_decision_); + + ACE_Hash<OBJECT_KEY> hash; + + // Look up the target in access_map_; if there, return the value, + // otherwise return the default value. + CORBA::Boolean access_decision; + if (this->access_map_.find (key, access_decision) == -1) + { + // Couldn't find the IOR in the map, so we use the default + access_decision = this->default_allowance_decision_; + if (TAO_debug_level >= 3) + ACE_DEBUG ((LM_DEBUG, + "TAO (%P|%t) SL2_AccessDecision::access_decision(%x,%s)" + " NOT FOUND using default %d\n", + hash.operator()(key), + operation_name, access_decision)); + } + else if (TAO_debug_level >= 3) + { + ACE_DEBUG ((LM_DEBUG, + "TAO (%P|%t) SL2_AccessDecision::access_decision(%x,%s)" + " found with decision %d\n", + hash.operator()(key), + operation_name, access_decision)); + } + + // For now we just return the default. + return access_decision; + +} + +CORBA::Boolean +TAO::Security::AccessDecision::access_allowed_ex ( + const char * orb_id, + const ::CORBA::OctetSeq & adapter_id, + const ::CORBA::OctetSeq & object_id, + const ::SecurityLevel2::CredentialsList & /*cred_list */, + const char * operation_name) +{ + OBJECT_KEY key; + key.orbid_ = orb_id; + key.adapter_id_ = adapter_id; + key.oid_ = object_id; + + return this->access_allowed_i (key, operation_name); +} + +CORBA::Boolean +TAO::Security::AccessDecision::access_allowed + (const ::SecurityLevel2::CredentialsList & /*cred_list */, + ::CORBA::Object_ptr target, + const char * operation_name, + const char * /*target_interface_name */) +{ + // @@ I still don't know what we do with the cred_list in here... + // Do we inspect it? + + // Turn the target into what we'll use as a key into the map. + OBJECT_KEY key = this->map_key_from_objref (target); + return this->access_allowed_i (key, operation_name); +} + +void +TAO::Security::AccessDecision::add_object + (const char * orb_id, + const ::CORBA::OctetSeq & adapter_id, + const ::CORBA::OctetSeq & object_id, + CORBA::Boolean allow_insecure_access) +{ + // make a key from 'obj' + OBJECT_KEY key; + key.orbid_ = orb_id; + key.adapter_id_ = adapter_id; + key.oid_ = object_id; + + // bind it into the access_map_, replacing anything that's there. + // LOCK THE MAP! + ACE_GUARD (TAO_SYNCH_MUTEX, guard, this->map_lock_); + + ACE_Hash<OBJECT_KEY> hash; + + // Since we want to replace any existing entry in the map, we just + // use rebind. + errno = 0; // Not sure if this gets set if rebind fails...it only + // appears to fail when an allocation thru the allocator's + // malloc() fails. Depending on the malloc() implementation, + // errno could get set OR an exception thrown. + int ret = this->access_map_.rebind (key, allow_insecure_access); + if (ret == -1) + { + // rebind shouldn't fail under normal circumstances + if (TAO_debug_level > 1) + ACE_DEBUG ((LM_DEBUG, + "TAO (%P|%t): SL2_AccessDecision::add_object(%x,%d) " + "unexpectedly failed (errno=%d)\n", + hash.operator()(key), + allow_insecure_access, + errno)); + throw + CORBA::NO_MEMORY(CORBA::SystemException::_tao_minor_code (TAO::VMCID, + errno), + CORBA::COMPLETED_NO); + } + else + { + if (TAO_debug_level >= 3) + ACE_DEBUG ((LM_DEBUG, + "TAO (%P|%t): SL2_AccessDecision::add_object(%x,%d) okay\n", + hash.operator()(key), + allow_insecure_access)); + } +} + +void +TAO::Security::AccessDecision::remove_object + (const char * orb_id, + const ::CORBA::OctetSeq & adapter_id, + const ::CORBA::OctetSeq & object_id) +{ + OBJECT_KEY key; + key.orbid_ = orb_id; + key.adapter_id_ = adapter_id; + key.oid_ = object_id; + + ACE_Hash<OBJECT_KEY> hash; + + // unbind it from access_map_, no matter if it's not in there... + // LOCK THE MAP! + ACE_GUARD (TAO_SYNCH_MUTEX, guard, this->map_lock_); + + errno = 0; + int ret = this->access_map_.unbind (key); + if (ret == -1) + { + if (errno == ENOENT) + { + // ignore b/c we don't care...maybe log a debug message for info + if (TAO_debug_level >= 3) + ACE_DEBUG ((LM_DEBUG, + "TAO (%P|%t): SL2_AccessDecision::remove_object(%x) " + "object not found in access map\n", + hash.operator()(key))); + } + else + { + if (TAO_debug_level > 0) + ACE_DEBUG ((LM_DEBUG, + "TAO (%P|%t): SL2_AccessDecision::remove_object(%x) " + " unexpected error during unbind from map (errno=%d\n)", + hash.operator()(key), + errno)); + throw + CORBA::UNKNOWN (CORBA::SystemException::_tao_minor_code (TAO::VMCID, + errno), + CORBA::COMPLETED_NO); + } + } +} + +CORBA::Boolean +TAO::Security::AccessDecision::default_decision (void) +{ + return this->default_allowance_decision_; +} + +void +TAO::Security::AccessDecision::default_decision (CORBA::Boolean d) +{ + this->default_allowance_decision_ = d; +} + +TAO_END_VERSIONED_NAMESPACE_DECL diff --git a/TAO/orbsvcs/orbsvcs/Security/SL2_SecurityManager.h b/TAO/orbsvcs/orbsvcs/Security/SL2_SecurityManager.h new file mode 100644 index 00000000000..32da7a31219 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Security/SL2_SecurityManager.h @@ -0,0 +1,226 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file SL2_SecurityManager.h + * + * $Id$ + * + * @author Chris Cleeland <cleeland@ociweb.com> + */ +//============================================================================= + + +#ifndef TAO_SL2_SECURITY_MANAGER_H +#define TAO_SL2_SECURITY_MANAGER_H + +#include /**/ "ace/pre.h" +#include "orbsvcs/Security/security_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "orbsvcs/SecurityC.h" +#include "orbsvcs/SecurityLevel2C.h" + +#include "tao/LocalObject.h" +#include "tao/PortableServer/PS_ForwardC.h" + +#include "ace/Hash_Map_Manager_T.h" +#include "ace/Null_Mutex.h" + +#if defined(_MSC_VER) +#pragma warning(push) +#pragma warning(disable:4250) +#endif /* _MSC_VER */ + + +TAO_BEGIN_VERSIONED_NAMESPACE_DECL + +namespace TAO +{ + // would prefer SL2, but all the other SL2 stuff is in the Security namespace + namespace Security + { + // This should move out of here probably, but it's easier to stick it + // here for the moment...(CJC) + /** + * @class AccessDecision + * + * @brief + */ + class AccessDecision + : public virtual TAO::SL2::AccessDecision, + public virtual TAO_Local_RefCounted_Object + { + public: + /*! Constructor */ + AccessDecision (/* not yet known */); + ~AccessDecision (void); + + virtual ::CORBA::Boolean access_allowed ( + const ::SecurityLevel2::CredentialsList & cred_list, + ::CORBA::Object_ptr target, + const char * operation_name, + const char * target_interface_name + ); + + virtual ::CORBA::Boolean access_allowed_ex ( + const char * orb_id, + const ::CORBA::OctetSeq & adapter_id, + const ::CORBA::OctetSeq & object_id, + const ::SecurityLevel2::CredentialsList & cred_list, + const char * operation_name); + + virtual ::CORBA::Boolean default_decision (void); + virtual void default_decision (::CORBA::Boolean d); + + virtual void add_object (const char * orbid, + const ::CORBA::OctetSeq & adapter_id, + const ::CORBA::OctetSeq & object_id, + ::CORBA::Boolean allow_insecure_access); + + virtual void remove_object (const char * orbid, + const ::CORBA::OctetSeq & adapter_id, + const ::CORBA::OctetSeq & object_id); + + private: + /*! + * This is the default value that's returned from access_allowed() + * when the access table doesn't contain an entry for the reference. + */ + ::CORBA::Boolean default_allowance_decision_; + + /*! + * Map containing references and their designated insecure access. + */ + // What sorts of maps are available in ACE? We'll be mapping + // an object reference to a boolean, basically. Looks like for + // now we'll map a stringified IOR to the boolean, and provide some + // (for now) simple keys and functions for comparing them. + // + // Locking on this needs to be exclusive to add_object, + // remove_object, and access_allowed. I think that the lock on the + // map itself will be sufficient, but we'll model this after the + // Active Object map in the POA...so whatever way that goes, so, too, + // will this. + struct ReferenceKeyType + { + PortableServer::ObjectId_var oid_; + CORBA::OctetSeq_var adapter_id_; + CORBA::String_var orbid_; + + // operations/methods necessary for functors in HashMap; might + // need to add operator< if we decide to use an RB_Tree + bool operator== (const ReferenceKeyType& other) const; + CORBA::ULong hash() const; + + // operator kind of like a "toString()" for debug statements + operator const char * () const; + }; + typedef ReferenceKeyType OBJECT_KEY; + // This is typedef'd because we might try to do something fancier + // where, rather than having just a string as the key, we have a + // structure and the structure precomputes some of the information + // for the actual key. Thus, we could then customize the hash and + // comparison functors so that they use the precomputed information + // rather than computing it each time. For now, though, I want to + // make this easy to get things working. + typedef ACE_Hash_Map_Manager_Ex<OBJECT_KEY, + CORBA::Boolean, // access_allowed? + ACE_Hash<OBJECT_KEY>, + ACE_Equal_To<OBJECT_KEY>, + ACE_Null_Mutex> // not sure this is right + ACCESS_MAP_TYPE; + + ACCESS_MAP_TYPE access_map_; + + // Lock for accessing the map. It may be possible to get away with + // just using a lock directly in the map, but I'm not sure, so I'll err + // conservatively. + TAO_SYNCH_MUTEX map_lock_; + + private: + /*! + * @brief Encapsulates a TAO-specific way to do object_to_string() without having an ORB reference handy. + * + * @note If OBJECT_KEY changes as described above, this should change + * so that it generates an OBJECT_KEY. + */ + OBJECT_KEY map_key_from_objref (CORBA::Object_ptr obj); + + // + // This is the private implementation that is common to both + // access_allowed and access_allowed_ex. + ::CORBA::Boolean access_allowed_i (OBJECT_KEY& key, + const char *operation_name); + + }; + + /** + * @class SecurityManager + * + * @brief + * + */ + class SecurityManager + : public virtual SecurityLevel2::SecurityManager, + public virtual TAO_Local_RefCounted_Object + { + public: + + /// Constructor + SecurityManager (/* not sure what's needed yet */); + + /** + * @name SecurityLevel2::SecurityManager Methods + * + * Methods required by the SecurityLevel2::SecurityManager + * interface. + */ + //@{ + virtual ::Security::MechandOptionsList* supported_mechanisms (); + virtual SecurityLevel2::CredentialsList* own_credentials (); + virtual SecurityLevel2::RequiredRights_ptr required_rights_object (); + virtual SecurityLevel2::PrincipalAuthenticator_ptr principal_authenticator (); + virtual SecurityLevel2::AccessDecision_ptr access_decision (); + virtual SecurityLevel2::AuditDecision_ptr audit_decision (); + virtual SecurityLevel2::TargetCredentials_ptr get_target_credentials (CORBA::Object_ptr o); + virtual void remove_own_credentials (SecurityLevel2::Credentials_ptr creds); + virtual CORBA::Policy_ptr get_security_policy (CORBA::PolicyType policy_type); + //@} + + protected: + + /// Destructor + /** + * Protected destructor to enforce proper memory management + * through the reference counting mechanism. + */ + virtual ~SecurityManager (void); + + private: + + /// The ORB-specific SecurityLevel2::PrincipalAuthenticator + /// reference. + // Except we're not going to have one of these right now + SecurityLevel2::PrincipalAuthenticator_var principal_authenticator_; + + // AccessDecision instance + SecurityLevel2::AccessDecision_var access_decision_; + }; + + } // End SL3 namespace +} // End TAO namespace + +TAO_END_VERSIONED_NAMESPACE_DECL + + +#if defined(_MSC_VER) +#pragma warning(pop) +#endif /* _MSC_VER */ + +#include /**/ "ace/post.h" + +#endif /* TAO_SL2_SECURITY_MANAGER_H */ diff --git a/TAO/orbsvcs/orbsvcs/Security/Security_ORBInitializer.cpp b/TAO/orbsvcs/orbsvcs/Security/Security_ORBInitializer.cpp index 970aff6e1dd..d6a665341a5 100644 --- a/TAO/orbsvcs/orbsvcs/Security/Security_ORBInitializer.cpp +++ b/TAO/orbsvcs/orbsvcs/Security/Security_ORBInitializer.cpp @@ -7,7 +7,10 @@ ACE_RCSID (Security, "$Id$") -// #include "Security_Current.h" +#if 1 +#include "orbsvcs/Security/Security_Current.h" +#include "orbsvcs/Security/SL2_SecurityManager.h" +#endif #include "orbsvcs/Security/SL3_SecurityCurrent.h" #include "orbsvcs/Security/SL3_CredentialsCurator.h" #include "orbsvcs/Security/SL3_SecurityManager.h" @@ -41,36 +44,57 @@ TAO::Security::ORBInitializer::pre_init ( throw CORBA::INTERNAL (); } -// // Reserve a TSS slot in the ORB core internal TSS resources for the -// // thread-specific portion of Security::Current. -// size_t old_tss_slot = tao_info->allocate_tss_slot_id (0 -//); + // Reserve a TSS slot in the ORB core internal TSS resources for the + // thread-specific portion of Security::Current. + size_t tss_slot = tao_info->allocate_tss_slot_id (0 /* no cleanup function */); -// CORBA::String_var orb_id = info->orb_id (); +#if 1 -// // Create the SecurityLevel2::Current object. -// SecurityLevel2::Current_ptr current = SecurityLevel2::Current::_nil (); -// ACE_NEW_THROW_EX (current, -// TAO_Security_Current (old_tss_slot, orb_id.in ()), -// CORBA::NO_MEMORY ( -// CORBA::SystemException::_tao_minor_code ( -// TAO::VMCID, -// ENOMEM), -// CORBA::COMPLETED_NO)); +#if 0 // why am I getting a BAD_OPERATION from no SSL context?! + CORBA::String_var orb_id = info->orb_id (); -// SecurityLevel2::Current_var security_current = current; + // Create the SecurityLevel2::Current object. + SecurityLevel2::Current_ptr current = SecurityLevel2::Current::_nil (); + ACE_NEW_THROW_EX (current, + TAO_Security_Current (tss_slot, orb_id.in ()), + CORBA::NO_MEMORY ( + CORBA::SystemException::_tao_minor_code ( + TAO::VMCID, + ENOMEM), + CORBA::COMPLETED_NO)); -// // Register the SecurityLevel2::Current object reference with the -// // ORB. -// info->register_initial_reference ("SecurityCurrent", -// security_current.in () -//); + SecurityLevel2::Current_var security_current = current; - // Reserve a TSS slot in the ORB core internal TSS resources for the - // thread-specific portion of SecurityLevel3::SecurityCurrent - // object. - size_t tss_slot = tao_info->allocate_tss_slot_id (0); + // Register the SecurityLevel2::Current object reference with the + // ORB. + info->register_initial_reference ("SecurityCurrent", + security_current.in ()); +#endif + /* + * Instantiate and register the SecurityLevel2::SecurityManager + */ + SecurityLevel2::SecurityManager_ptr manager2; + ACE_NEW_THROW_EX (manager2, + TAO::Security::SecurityManager (/*need args*/), + CORBA::NO_MEMORY ( + CORBA::SystemException::_tao_minor_code ( + TAO::VMCID, + ENOMEM), + CORBA::COMPLETED_NO)); + + SecurityLevel2::SecurityManager_var security_manager2 = manager2; + + // Register the SecurityLevel2::SecurityManager object reference + // with the ORB. + info->register_initial_reference ("SecurityLevel2:SecurityManager", + security_manager2.in ()); + +#endif + // Rather than reserve another TSS slot in the ORB core internal TSS + // resources for the thread-specific portion of + // SecurityLevel3::SecurityCurrent object, we will re-use the slot + // allocated earlier. // Create the SecurityLevel3::Current object. SecurityLevel3::SecurityCurrent_ptr current3; diff --git a/TAO/orbsvcs/orbsvcs/SecurityLevel2.idl b/TAO/orbsvcs/orbsvcs/SecurityLevel2.idl index 4826c449ed4..c59afee58bc 100644 --- a/TAO/orbsvcs/orbsvcs/SecurityLevel2.idl +++ b/TAO/orbsvcs/orbsvcs/SecurityLevel2.idl @@ -189,7 +189,6 @@ module SecurityLevel2 { ); }; - // Policy interfaces to control bindings local interface QOPPolicy : CORBA::Policy { @@ -271,4 +270,38 @@ module SecurityLevel2 { #pragma prefix "" +module TAO { + module SL2 { + local interface AccessDecision : SecurityLevel2::AccessDecision + { + /* TAO-specific access_allowed that works around deficiencies in + the SecurityLevel2::AccessDecision::access_allowed() operation. */ + // Parameter object_id should be PortableInterceptor::ObjectId, but + // using that type would require including the PI_Forward.pidl file. + // By using the real type, we can avoid that dependency. + boolean access_allowed_ex (in ::CORBA::ORBid orb_id, + in ::CORBA::OctetSeq adapter_id, + in ::CORBA::OctetSeq object_id, + in ::SecurityLevel2::CredentialsList cred_list, + in ::CORBA::Identifier operation_name); + + /*! Default value returned when a reference is not in the list. */ + // Can't come up with a good name for this. + attribute boolean default_decision; + + /*! Establish whether a particular object can be accessed via insecure + means. */ + void add_object (in ::CORBA::ORBid orb_id, + in ::CORBA::OctetSeq adapter_id, + in ::CORBA::OctetSeq object_id, + in boolean allow_insecure_access); + void remove_object (in ::CORBA::ORBid orb_id, + in ::CORBA::OctetSeq adapter_id, + in ::CORBA::OctetSeq object_id); + + // Should there be some kind of "find" interface? + }; + }; +}; + #endif /* _SECURITY_LEVEL_2_IDL_ */ diff --git a/TAO/orbsvcs/tests/Security/mixed_security_test/Foo.idl b/TAO/orbsvcs/tests/Security/mixed_security_test/Foo.idl new file mode 100644 index 00000000000..d52d94a51c2 --- /dev/null +++ b/TAO/orbsvcs/tests/Security/mixed_security_test/Foo.idl @@ -0,0 +1,32 @@ +// -*- IDL -*- + +//============================================================================= +/** + * @file Foo.idl + * + * $Id$ + * + * IDL for the Secure_Invocation test. + * + * @author Ossama Othman <ossama@uci.edu> + */ +//============================================================================= + +module Foo +{ + interface Bar + { + /// Exception that indicates that no security attributes were + /// available during the upcall. If this exception is thrown, + /// then is most likely a problem with the underlying security + /// mechanism(s). + exception NoSecurityAttributes {}; + + /// Test method. + void baz () raises (NoSecurityAttributes); + + /// Shutdown the server. + oneway void shutdown (); + }; + +}; diff --git a/TAO/orbsvcs/tests/Security/mixed_security_test/Foo_i.cpp b/TAO/orbsvcs/tests/Security/mixed_security_test/Foo_i.cpp new file mode 100644 index 00000000000..8b84c51e054 --- /dev/null +++ b/TAO/orbsvcs/tests/Security/mixed_security_test/Foo_i.cpp @@ -0,0 +1,66 @@ +// -*- C++ -*- + +#include "Foo_i.h" + +#include "ace/OS_NS_string.h" + + +ACE_RCSID (Secure_Invocation, + Foo_i, + "$Id$") + + +Foo_i::Foo_i (CORBA::ORB_ptr orb, + SecurityLevel3::SecurityCurrent_ptr current) + : orb_ (CORBA::ORB::_duplicate (orb)), + current_ (SecurityLevel3::SecurityCurrent::_duplicate (current)) +{ +} + +void +Foo_i::baz () + ACE_THROW_SPEC ((CORBA::SystemException, + Foo::Bar::NoSecurityAttributes)) +{ + if (this->current_ == 0) + { + ACE_DEBUG ((LM_DEBUG, "FOO (%P|%t) No ClientCredentials available \n")); + return; + } + + try + { + SecurityLevel3::ClientCredentials_var credentials = + this->current_->client_credentials (); + + CORBA::String_var id = credentials->creds_id (); + + ACE_DEBUG ((LM_DEBUG, + "FOO (%P|%t) ClientCredentials ID: %s\n", id.in ())); + return; + } + catch (const CORBA::BAD_INV_ORDER &ex) + { + ACE_DEBUG ((LM_INFO, + "FOO (%P|%t) Caught BAD_INV_ORDER exception trying to obtain " + "client credentials. This is okay if the invocation was via " + "non-secured means.\n")); + ex._tao_print_exception ("obtaining client credentials"); + // should we re-throw? No, because what we're testing is whether + // we go into this method, not whether the method itself operates + // properly. + } + catch (CORBA::Exception& ex) + { + ACE_DEBUG ((LM_ERROR, "FOO (%P|%t) Caught exception, trying to obtain ClientCredentials")); + ACE_PRINT_EXCEPTION (ex, "Exception"); + } + +} + +void +Foo_i::shutdown () + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + this->orb_->shutdown (0); +} diff --git a/TAO/orbsvcs/tests/Security/mixed_security_test/Foo_i.h b/TAO/orbsvcs/tests/Security/mixed_security_test/Foo_i.h new file mode 100644 index 00000000000..1b1cef77b7a --- /dev/null +++ b/TAO/orbsvcs/tests/Security/mixed_security_test/Foo_i.h @@ -0,0 +1,48 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Foo_i.h + * + * $Id$ + * + * Implementation header for the Secure_Invocation test. + * + * @author Ossama Othman <ossama@uci.edu> + */ +//============================================================================= + +#ifndef SECURE_INVOCATION_FOO_I_H +#define SECURE_INVOCATION_FOO_I_H + +#include "FooS.h" +#include "orbsvcs/SecurityLevel3C.h" + +class Foo_i : public virtual POA_Foo::Bar + , public virtual PortableServer::RefCountServantBase +{ +public: + + /// Constructor. + Foo_i (CORBA::ORB_ptr, + SecurityLevel3::SecurityCurrent_ptr); + + /// Test method. + virtual void baz (ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException, + Foo::Bar::NoSecurityAttributes)); + + virtual void shutdown (ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException)); + +private: + + /// Reference to the ORB. + CORBA::ORB_var orb_; + + /// Reference to the "SecurityCurrent" object. + SecurityLevel3::SecurityCurrent_var current_; + +}; + +#endif /* SECURE_INVOCATION_FOO_I_H */ diff --git a/TAO/orbsvcs/tests/Security/mixed_security_test/README b/TAO/orbsvcs/tests/Security/mixed_security_test/README new file mode 100644 index 00000000000..422bd9a09d8 --- /dev/null +++ b/TAO/orbsvcs/tests/Security/mixed_security_test/README @@ -0,0 +1,76 @@ +# +# $Id$ +# + +----------------------------- +cases: + +1. ior has secure profile, client is secured, object in permitted list +2. ior has secure profile, client unsecured, object NOT in permitted list +3. ior has unsecure profile, client is secured, object +----------------------------- + + +This test verifies that the ORB's secure invocation mechanism is +functioning properly. It expands on what the Secure_Invocation does +by activating an object with two separate ORBs and POAs. One of the POAs +has a SecQoPNoProtection policy assigned and thus should permit also +invocations over non-secure transport. + +The test verifies that a secure client can make invocations, using both +the "secure" and the "non-secure" IOR from the server. Note that for +the server to support the non-secure invocations it must have -SSLNoProtection +in its sevice configuration file. + +The test verifies that a non-secure client can only make invocations through +the "non-secure" IOR from the server. An invocation through the "secure" IOR +results in CORBA::NO_PERMISSION exception. + +The expected test output is the following (actual "certificate issuer" +contents may differ): + + +==== Running Secure_Invocation_Two_Orb test +==== Spawning a server with two ORBs ... + +==== Secure Client - Secure Server IOR: expected to pass +==== Running: client -ORBSvcConf client.conf -k file://server-ssliop.ior -x +FOO (10429|3086433200) ClientCredentials ID: X509: 06 + +Secure_Invocation_Two_Orb test passed. + +==== Secure Client - Non Secure Server IOR: expected to pass +==== Running: client -ORBSvcConf client.conf -k file://server-iiop.ior -x +FOO (10429|3075943344) ClientCredentials ID: X509: 06 +(10429|3086436832) event loop finished + +Secure_Invocation_Two_Orb test passed. + +==== Spawning a server with two ORBs ... + +==== Non Secure Client - Non Secure Server IOR: expected to pass +==== Running: client -k file://server-iiop.ior -x +FOO (10434|3075759024) Caught exception, trying to obtain ClientCredentials(10434|3075759024) EXCEPTION, Exception +system exception, ID 'IDL:omg.org/CORBA/BAD_INV_ORDER:1.0' +Unknown vendor minor code id (0), minor code = 0, completed = NO + + +Secure_Invocation_Two_Orb test passed. + +==== Non Secure Client - Secure Server IOR: expected to fail +==== Running: client -k file://server-ssliop.ior -x +SSLIOP (10434|3086248880) No SSL and a higher QoP (0x3) is required (than 0x0) +(10438|3086280384) EXCEPTION, Caught exception: +system exception, ID 'IDL:omg.org/CORBA/NO_PERMISSION:1.0' +Unknown vendor minor code id (0), minor code = 0, completed = NO + +ERROR: client returned 1 + +==== Secure Client - Secure Server IOR: expected to pass + (and cause destruction to the secure server ORB) +==== Running: client -ORBSvcConf client.conf -k file://server-ssliop.ior -x +FOO (10434|3086248880) ClientCredentials ID: X509: 06 +(10434|3086252512) event loop finished + +Secure_Invocation_Two_Orb test passed. + diff --git a/TAO/orbsvcs/tests/Security/mixed_security_test/cacert.pem b/TAO/orbsvcs/tests/Security/mixed_security_test/cacert.pem new file mode 100644 index 00000000000..a9e905f4e6c --- /dev/null +++ b/TAO/orbsvcs/tests/Security/mixed_security_test/cacert.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDfTCCAuagAwIBAgIBADANBgkqhkiG9w0BAQQFADCBjDELMAkGA1UEBhMCVVMx +CzAJBgNVBAgTAkNBMQ8wDQYDVQQHEwZJcnZpbmUxEjAQBgNVBAoTCURPQyBHcm91 +cDEQMA4GA1UECxYHVUNJX0RPQzERMA8GA1UEAxMIUHJpeWFua2ExJjAkBgkqhkiG +9w0BCQEWF3Bnb250bGFAZG9jLmVjZS51Y2kuZWR1MB4XDTAxMDYxMTE3MjI0MVoX +DTExMDYwOTE3MjI0MVowgYwxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEPMA0G +A1UEBxMGSXJ2aW5lMRIwEAYDVQQKEwlET0MgR3JvdXAxEDAOBgNVBAsWB1VDSV9E +T0MxETAPBgNVBAMTCFByaXlhbmthMSYwJAYJKoZIhvcNAQkBFhdwZ29udGxhQGRv +Yy5lY2UudWNpLmVkdTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAyFiCRDUH +nGJqQG9jT/2PhZUAgfwXvIwfDM8m/WujCt/buDcrOz767shBsk4HZhW91Vm4mE03 +K1zfCzojRigf28uyB/rlp60p2Fq0wvZBNNU5Muia6esleR4unb4QslOpcFhct/9n +UPnlnnsZOTaGWaELNKEjYfHqPh8PQ0lYurECAwEAAaOB7DCB6TAdBgNVHQ4EFgQU +0Y6IZjkLbLbtZ5aoKLcfd7Yc/kYwgbkGA1UdIwSBsTCBroAU0Y6IZjkLbLbtZ5ao +KLcfd7Yc/kahgZKkgY8wgYwxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEPMA0G +A1UEBxMGSXJ2aW5lMRIwEAYDVQQKEwlET0MgR3JvdXAxEDAOBgNVBAsWB1VDSV9E +T0MxETAPBgNVBAMTCFByaXlhbmthMSYwJAYJKoZIhvcNAQkBFhdwZ29udGxhQGRv +Yy5lY2UudWNpLmVkdYIBADAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBAUAA4GB +AHYi8ulIzUI3p3+Ma16rumZxvKcmkJJbU6fpAv4ZvK6AWyy+6Ja0GD5N3SGEx+xU +nMffTR+LePa9PAZiR7dNkF6ikPxXZu4jn8KY2zFT3SB/VjCoEetR9i9QI//O0Fea +3yZ0NygNWe5cyVDLCb4meucJpsClfyL28DWzMwD2liX3 +-----END CERTIFICATE----- diff --git a/TAO/orbsvcs/tests/Security/mixed_security_test/client.conf b/TAO/orbsvcs/tests/Security/mixed_security_test/client.conf new file mode 100644 index 00000000000..5847fa22a03 --- /dev/null +++ b/TAO/orbsvcs/tests/Security/mixed_security_test/client.conf @@ -0,0 +1,4 @@ +# $Id$ + +dynamic SSLIOP_Factory Service_Object * TAO_SSLIOP:_make_TAO_SSLIOP_Protocol_Factory() "-SSLAuthenticate SERVER_AND_CLIENT -SSLPrivateKey PEM:client_key.pem -SSLCertificate PEM:client_cert.pem" +static Resource_Factory "-ORBProtocolFactory SSLIOP_Factory" diff --git a/TAO/orbsvcs/tests/Security/mixed_security_test/client.conf.xml b/TAO/orbsvcs/tests/Security/mixed_security_test/client.conf.xml new file mode 100644 index 00000000000..f68baa15979 --- /dev/null +++ b/TAO/orbsvcs/tests/Security/mixed_security_test/client.conf.xml @@ -0,0 +1,9 @@ +<?xml version='1.0'?> +<!-- Converted from ./orbsvcs/tests/Security/Secure_Invocation/client.conf by svcconf-convert.pl --> +<ACE_Svc_Conf> + <!-- $Id$ --> + <dynamic id="SSLIOP_Factory" type="Service_Object"> + <initializer path="TAO_SSLIOP" init="_make_TAO_SSLIOP_Protocol_Factory" params="-SSLAuthenticate SERVER_AND_CLIENT -SSLPrivateKey PEM:client_key.pem -SSLCertificate PEM:client_cert.pem"/> + </dynamic> + <static id="Resource_Factory" params="-ORBProtocolFactory SSLIOP_Factory"/> +</ACE_Svc_Conf> diff --git a/TAO/orbsvcs/tests/Security/mixed_security_test/client.cpp b/TAO/orbsvcs/tests/Security/mixed_security_test/client.cpp new file mode 100644 index 00000000000..3b858b39362 --- /dev/null +++ b/TAO/orbsvcs/tests/Security/mixed_security_test/client.cpp @@ -0,0 +1,213 @@ +// -*- C++ -*- + +#include "ace/Get_Opt.h" +#include "ace/SString.h" + +#include "orbsvcs/SecurityC.h" + +#include "FooC.h" +#include "constants.h" + +ACE_RCSID (Secure_Invocation, + client, + "$Id$") + +bool shutdown_server = true; + +class ClientTest +{ +public: + struct Results + { + bool secure; + bool non_secure; + bool successful; // set by "run" if actual meets expected + + Results(bool sec = false, bool nsec = false) + : secure(sec), non_secure(nsec), successful(false) { } + }; + + ClientTest (CORBA::ORB_ptr orb, const char* ior); + + /*! + * Creates a Security::QOPPolicy with the Quality-of-Protection set + * to "no protection." It then invokes a method on @c obj_ via a + * non-secured transport, which should then result in a @c + * CORBA::NO_PERMISSION exception. + */ + bool non_secure_invocation (); + bool secure_invocation (); + + Results run(const Results& expected_results); + +private: + CORBA::ORB_var orb_; + Foo::Bar_var obj_; +}; + +ClientTest::ClientTest (CORBA::ORB_ptr orb, const char* ior) + : orb_(CORBA::ORB::_duplicate (orb)) +{ + CORBA::Object_var o = this->orb_->string_to_object (ior); + if (CORBA::is_nil (o.in())) + throw CORBA::INTERNAL (); + + this->obj_ = Foo::Bar::_narrow (o.in ()); +} + +ClientTest::Results +ClientTest::run (const ClientTest::Results& expected) +{ + Results actual; +#if 1 + actual.non_secure = this->non_secure_invocation (); +#else + actual.non_secure = true; +#endif + actual.secure = this->secure_invocation (); + + actual.successful = (expected.secure == actual.secure + && expected.non_secure == actual.non_secure); + + return actual; +} + +bool +ClientTest::non_secure_invocation () +{ + ACE_DEBUG ((LM_DEBUG, "mixed_security/client: invoking via non-secured means\n")); + // Disable protection for this insecure invocation test. + + Security::QOP qop = Security::SecQOPNoProtection; + + CORBA::Any no_protection; + no_protection <<= qop; + + // Create the Security::QOPPolicy. + CORBA::Policy_var policy = + this->orb_->create_policy (Security::SecQOPPolicy, + no_protection); + + CORBA::PolicyList policy_list (1); + policy_list.length (1); + policy_list[0] = CORBA::Policy::_duplicate (policy.in ()); + + // Create an object reference that uses plain IIOP (i.e. no + // protection). + CORBA::Object_var object = + this->obj_->_set_policy_overrides (policy_list, + CORBA::SET_OVERRIDE); + + Foo::Bar_var server = + Foo::Bar::_narrow (object.in ()); + + if (CORBA::is_nil (server.in ())) + { + ACE_ERROR ((LM_ERROR, + "(%P|%t) ERROR: Failed to narrow override reference to " + "Foo::Bar type.\n")); + + throw CORBA::INTERNAL (); + } + + bool invocation_succeeded = true; + try + { + // This invocation should result in a CORBA::NO_PERMISSION + // exception. + server->baz (); + ACE_DEBUG ((LM_DEBUG, "mixed_security/client: non-secured invocation succeeded\n")); + } + catch (const CORBA::NO_PERMISSION& exc) + { + ACE_DEBUG ((LM_DEBUG, + "ClientTest::non_secure_invocation: got NO_PERMISSION\n")); + invocation_succeeded = false; + } + + return invocation_succeeded; +} + +bool +ClientTest::secure_invocation () +{ + ACE_DEBUG ((LM_DEBUG, "mixed_security/client: invoking via secure means\n")); + + // In this test, any NO_PERM exception is a failure. + bool invocation_succeeded = true; + try + { + // This invocation should return successfully. + this->obj_->baz (); + ACE_DEBUG ((LM_DEBUG, "mixed_security/client: secured invocation succeeded\n")); + } + catch (const CORBA::NO_PERMISSION&) + { + ACE_DEBUG ((LM_DEBUG, + "ClientTest::secure_invocation: got NO_PERMISSION\n")); + invocation_succeeded = false; + } + + return invocation_succeeded; +} + +int +main (int argc, char *argv[]) +{ + // Accomodate deficiencies on Windows that preclude doing this in + // run_test.pl + ACE_TString env ("SSL_CERT_FILE="); + env += TAO_Mixed_Security_Test::cert_file; + ACE_OS::putenv (env.c_str ()); + + try + { + CORBA::ORB_var orb = CORBA::ORB_init (argc, argv, ""); + + ClientTest restricted (orb.in (), + TAO_Mixed_Security_Test::restricted_ior); + + // Run the restricted test + ClientTest::Results restricted_results = + restricted.run (ClientTest::Results(true, false)); + ACE_DEBUG ((LM_DEBUG, + "===> Restricted test %s: secure=%d, non-secure=%d\n", + restricted_results.successful ? "PASSED" : "FAILED", + restricted_results.secure, + restricted_results.non_secure)); + + ACE_DEBUG ((LM_DEBUG, "mixed_security/client: set up permitted test\n")); + // Run the permitted test + ClientTest permitted (orb.in (), + TAO_Mixed_Security_Test::permitted_ior); + + ACE_DEBUG ((LM_DEBUG, "mixed_security/client: running permitted test\n")); + ClientTest::Results permitted_results = + permitted.run (ClientTest::Results(true, true)); + ACE_DEBUG ((LM_DEBUG, + "===> Permitted test %s: secure=%d, non-secure=%d\n", + permitted_results.successful ? "PASSED" : "FAILED", + permitted_results.secure, + permitted_results.non_secure)); + + // The server ORB *is* shutdown by this test, if explicitly requested + // @@ at this point there's no way to specify this...but I should + if (shutdown_server) + { + CORBA::Object_var o = + orb->string_to_object (TAO_Mixed_Security_Test::permitted_ior); + Foo::Bar_var foo = Foo::Bar::_narrow (o.in()); + foo->shutdown (); + } + + orb->destroy (); + } + catch (CORBA::Exception& ex) + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, + "Caught exception:"); + return 1; + } + + return 0; +} diff --git a/TAO/orbsvcs/tests/Security/mixed_security_test/client_cert.pem b/TAO/orbsvcs/tests/Security/mixed_security_test/client_cert.pem new file mode 100644 index 00000000000..0bebb696cfc --- /dev/null +++ b/TAO/orbsvcs/tests/Security/mixed_security_test/client_cert.pem @@ -0,0 +1,16 @@ +-----BEGIN CERTIFICATE----- +MIICgzCCAewCAQYwDQYJKoZIhvcNAQEEBQAwgYwxCzAJBgNVBAYTAlVTMQswCQYD +VQQIEwJDQTEPMA0GA1UEBxMGSXJ2aW5lMRIwEAYDVQQKEwlET0MgR3JvdXAxEDAO +BgNVBAsWB1VDSV9ET0MxETAPBgNVBAMTCFByaXlhbmthMSYwJAYJKoZIhvcNAQkB +FhdwZ29udGxhQGRvYy5lY2UudWNpLmVkdTAeFw0wMTA2MTExODEwMzRaFw0xMTA2 +MDkxODEwMzRaMIGGMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExDzANBgNVBAcT +BklydmluZTEQMA4GA1UEChMHVEFPK09DSTEMMAoGA1UECxMDT0NJMREwDwYDVQQD +EwhQcml5YW5rYTEmMCQGCSqGSIb3DQEJARYXcGdvbnRsYUBkb2MuZWNlLnVjaS5l +ZHUwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAL6f8pBX7Mi3FPY/OYBOq+kb +wQ3WX0Z8+nDxd7AiWDAx2AL5EaX8xnUiRi96OJ+CYPCYOUlavGVzZkRVMFdOuHAn +RvY2sCpvU2rkKpEx9Pd50l7FLnXJuflnRc6zIEKOvuQcPJvsP4AaxaFxTnZExXQJ +kDEiQP3mGID/eXtUzywbAgMBAAEwDQYJKoZIhvcNAQEEBQADgYEAuvSoOnMB6sxj +ft9YbdLeyATTPzHbxAb6zQo72DUmM3roNowUrefHymU8jZoC6HeaROeKCU0MkVes +l/jYlz/OwSYkbyGNIUkq4DHEWKzXEg8M603fsWK6IK3T5iPBHY+l/mYSEHJPfypZ +fl/y4YSNJZlrz6kCIHTcwfHXDRC1mjM= +-----END CERTIFICATE----- diff --git a/TAO/orbsvcs/tests/Security/mixed_security_test/client_key.pem b/TAO/orbsvcs/tests/Security/mixed_security_test/client_key.pem new file mode 100644 index 00000000000..1428b501712 --- /dev/null +++ b/TAO/orbsvcs/tests/Security/mixed_security_test/client_key.pem @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICXAIBAAKBgQC+n/KQV+zItxT2PzmATqvpG8EN1l9GfPpw8XewIlgwMdgC+RGl +/MZ1IkYvejifgmDwmDlJWrxlc2ZEVTBXTrhwJ0b2NrAqb1Nq5CqRMfT3edJexS51 +ybn5Z0XOsyBCjr7kHDyb7D+AGsWhcU52RMV0CZAxIkD95hiA/3l7VM8sGwIDAQAB +AoGABGaa6fwtqkCXykuRX0XxsBME9PXTA0SVX5AjjDxuvsYXz5HCd4uLZV7iMexn +bD9NT6CkCe5/VPRCEyfIUuutVFc7lkPwuRw5FvNcf4gMH9ltufQfH/KeR7d2Jvge +zrTOH7nicshy67mfOEOaoDphWoT9uy+7ayym+EsJLJU37VkCQQD6xLRu5r9tKX2/ +NfIQsGxF3TZyXgxcuxMh9JOq5E9nBwhr1JaXDbXktXfIK/F3XWHLFS8CIg6PhgGY +i/+UtGzvAkEAwpoHp89U2jLdVRoIcwy5o7Ocwk3HCXem3UgFWXzzunGM1x+ozDFA +uo5nyXiAO6Buka9C2czje275kE18BbqLlQJBAMJNf/EeYdzXdVOfHPzJdlt72CAt +ty5y1ZRNyc10MgIGdQP4KObJ/NJFuZYkVmjCtm+A7neco+OZVcs5TsOOOYkCQBHQ +6EKEyM/xODJCX+OolpZWK1PeqwpC2hQIM/Uta2L2Yl6Pl3SaTcLGptnbHmJXHchY +s1YdW/ZBArgjX+dmXMECQApTKWbVLmNsEoOlHU/I/KhGsfuojrzBMMe3FKLiHpmu +u86L3vu3OGZFcPgjazxWZcip8JekeJ7c+6suLNNRQ5I= +-----END RSA PRIVATE KEY----- diff --git a/TAO/orbsvcs/tests/Security/mixed_security_test/client_key_nopasswd.pem b/TAO/orbsvcs/tests/Security/mixed_security_test/client_key_nopasswd.pem new file mode 100644 index 00000000000..35e449a2493 --- /dev/null +++ b/TAO/orbsvcs/tests/Security/mixed_security_test/client_key_nopasswd.pem @@ -0,0 +1,16 @@ +RSA key ok +-----BEGIN RSA PRIVATE KEY----- +MIICXAIBAAKBgQDBuQXJQhW75XZJfatysGHE3/RXFeMSB8TOk/geXhlUAQTaHj/0 ++eQLNnz2ed8XFoyZFJYioUrcAHyC3LGv7CemhPAW0ZEBgXG8QX1eG8T+NlPh5pC8 +pMg8R67aVr/Rs3jvXsh7lI5rqCQ6Mr1fCg6qVdnJyH04gKKv4b0Iu29FDQIDAQAB +AoGADRU7yM3HvfrPNENicspqr+sYC1GVFkCkD/d6SEK+nye6diiY1SiTOBaj9dlh +MaP6NtRnF0uhTJ5TylqxPVpLixs6Dot/lX0Mu/bD80Zez1bWdQFivszOcDnxylHX +j4z3Sv5nSPWoOgssDVxWNpI9QHcC2E7zII094drJEG/UZIECQQDy0axJBAahSgMX +9CfpWJjXEMKD58RwddbiS2tGboLzdYXUVaE1qr4GN70jypGC4HmWZ6XV5HX4+fy3 +QltXF3GdAkEAzD0VpmOCan7jLty6+qklEwpyzMDJ9VH9QwfMyS5oSO4Dh08lC6WT +Ss+nQlXFwFYszKxd6kznEECGPlKybiC+MQJBANFdsKuUaRMQ+fHhd7hfyAlITi/l +2x8MvCeK2Ah2qTq6jpYy7zmS6x35WYBO3YB3hN8Gp5rxzjbLdfedo5xIfpECQGkk +ASM5EwhT7gxP4YnszYMx28uAa/d4j9KUD156H4F71iEwIzgNsvfOUqKZmUXclw9+ +pJJbqI/7R6CJ3gVHoeECQGpfgurJz2V5Z2/qsZIDJXgxFoW6vY9rZbZU80ZYx3Cb +RINCjB0G0ThsqH7FqCC3PAkEt0xThXqT2SM8ezVlENM= +-----END RSA PRIVATE KEY----- diff --git a/TAO/orbsvcs/tests/Security/mixed_security_test/client_none.conf b/TAO/orbsvcs/tests/Security/mixed_security_test/client_none.conf new file mode 100644 index 00000000000..b351c69d88a --- /dev/null +++ b/TAO/orbsvcs/tests/Security/mixed_security_test/client_none.conf @@ -0,0 +1,4 @@ +# $Id$ + +dynamic SSLIOP_Factory Service_Object * TAO_SSLIOP:_make_TAO_SSLIOP_Protocol_Factory() "-SSLAuthenticate NONE -SSLPrivateKey PEM:client_key.pem -SSLCertificate PEM:client_cert.pem" +static Resource_Factory "-ORBProtocolFactory SSLIOP_Factory" diff --git a/TAO/orbsvcs/tests/Security/mixed_security_test/client_nopasswd.conf b/TAO/orbsvcs/tests/Security/mixed_security_test/client_nopasswd.conf new file mode 100644 index 00000000000..c485fa19f3a --- /dev/null +++ b/TAO/orbsvcs/tests/Security/mixed_security_test/client_nopasswd.conf @@ -0,0 +1,4 @@ +# $Id$ + +dynamic SSLIOP_Factory Service_Object * TAO_SSLIOP:_make_TAO_SSLIOP_Protocol_Factory() "-SSLAuthenticate NONE -SSLPrivateKey PEM:client_key_nopasswd.pem -SSLCertificate PEM:client_cert.pem" +static Resource_Factory "-ORBProtocolFactory SSLIOP_Factory" diff --git a/TAO/orbsvcs/tests/Security/mixed_security_test/client_nopasswd.conf.xml b/TAO/orbsvcs/tests/Security/mixed_security_test/client_nopasswd.conf.xml new file mode 100644 index 00000000000..8060c28b75a --- /dev/null +++ b/TAO/orbsvcs/tests/Security/mixed_security_test/client_nopasswd.conf.xml @@ -0,0 +1,9 @@ +<?xml version='1.0'?> +<!-- Converted from ./orbsvcs/tests/Security/Secure_Invocation/client_nopasswd.conf by svcconf-convert.pl --> +<ACE_Svc_Conf> + <!-- $Id$ --> + <dynamic id="SSLIOP_Factory" type="Service_Object"> + <initializer path="TAO_SSLIOP" init="_make_TAO_SSLIOP_Protocol_Factory" params="-SSLAuthenticate NONE -SSLPrivateKey PEM:client_key_nopasswd.pem -SSLCertificate PEM:client_cert.pem"/> + </dynamic> + <static id="Resource_Factory" params="-ORBProtocolFactory SSLIOP_Factory"/> +</ACE_Svc_Conf> diff --git a/TAO/orbsvcs/tests/Security/mixed_security_test/constants.h b/TAO/orbsvcs/tests/Security/mixed_security_test/constants.h new file mode 100644 index 00000000000..ee5be237f6b --- /dev/null +++ b/TAO/orbsvcs/tests/Security/mixed_security_test/constants.h @@ -0,0 +1,29 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file constants.h + * + * $Id$ + * + * Set of constants shared between client and server + * + * @author Chris Cleeland <cleeland@ociweb.com> + */ +//============================================================================= + +#ifndef SECURE_INVOCATION_CONSTANTS_H +#define SECURE_INVOCATION_CONSTANTS_H + +namespace TAO_Mixed_Security_Test +{ + const char *cert_file = "cacert.pem"; + + const char *permitted_ior_file = "permitted.ior"; + const char *permitted_ior = "file://permitted.ior"; + + const char *restricted_ior_file = "restricted.ior"; + const char *restricted_ior = "file://restricted.ior"; +}; + +#endif diff --git a/TAO/orbsvcs/tests/Security/mixed_security_test/mixed_security.mpc b/TAO/orbsvcs/tests/Security/mixed_security_test/mixed_security.mpc new file mode 100644 index 00000000000..d22ba5a1120 --- /dev/null +++ b/TAO/orbsvcs/tests/Security/mixed_security_test/mixed_security.mpc @@ -0,0 +1,19 @@ +// -*- MPC -*- +// $Id$ + +project(*security server): taoexe, portableserver, orbsvcslib, security, ssliop { + exename = server + Source_Files { + Foo_i.cpp + server.cpp + } +} + +project(*security client): taoexe, orbsvcslib, security { + exename = client + Source_Files { + FooC.cpp + client.cpp + } +} + diff --git a/TAO/orbsvcs/tests/Security/mixed_security_test/run_test.pl b/TAO/orbsvcs/tests/Security/mixed_security_test/run_test.pl new file mode 100755 index 00000000000..7c343577b1c --- /dev/null +++ b/TAO/orbsvcs/tests/Security/mixed_security_test/run_test.pl @@ -0,0 +1,64 @@ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' + & eval 'exec perl -S $0 $argv:q' + if 0; + +# -*- perl -*- +# $Id$ + + +use lib "$ENV{ACE_ROOT}/bin"; +use PerlACE::Run_Test; + +$status = 0; +$restricted = PerlACE::LocalFile ("restricted.ior"); +$permitted = PerlACE::LocalFile ("permitted.ior"); + + +unlink $restricted; +unlink $permitted; + +$status = 0; + +# Set the SSL environment +# This doesn't work on Windows. For some reason, +# environment variables aren't propagated to child processes. +#$ENV{'SSL_CERT_FILE'} = 'cacert.pem'; + +$SV = new PerlACE::Process ("server", + "-ORBSvcConf server$PerlACE::svcconf_ext"); +$CL = new PerlACE::Process ("client", + "-ORBSvcConf client$PerlACE::svcconf_ext"); + +print STDERR "\n\n==== Running mixed_security_test test\n"; + +$SV->Spawn (); + +if (PerlACE::waitforfile_timed ($permitted, 15) == -1) { + print STDERR "ERROR: cannot find file <$permitted>\n"; + $SV->Kill (); + exit 1; +} + +if (PerlACE::waitforfile_timed ($restricted, 15) == -1) { + print STDERR "ERROR: cannot find file <$restricted>\n"; + $SV->Kill (); + exit 1; +} + +$client = $CL->SpawnWaitKill (60); + +if ($client != 0) { + print STDERR "ERROR: client returned $client\n"; + $status = 1; +} + +$server = $SV->WaitKill (5); + +if ($server != 0) { + print STDERR "ERROR: server returned $server\n"; + $status = 1; +} + +unlink $file; + +exit $status; diff --git a/TAO/orbsvcs/tests/Security/mixed_security_test/server.conf b/TAO/orbsvcs/tests/Security/mixed_security_test/server.conf new file mode 100644 index 00000000000..52ecf6d11ff --- /dev/null +++ b/TAO/orbsvcs/tests/Security/mixed_security_test/server.conf @@ -0,0 +1,7 @@ +# $Id$ + +dynamic SSLIOP_Factory Service_Object * +TAO_SSLIOP:_make_TAO_SSLIOP_Protocol_Factory() "-SSLAuthenticate SERVER_AND_CLIENT -SSLPrivateKey PEM:server_key.pem -SSLCertificate PEM:server_cert.pem" +# static Resource_Factory "-ORBProtocolFactory IIOP_Factory -ORBProtocolFactory SSLIOP_Factory" +# static Resource_Factory "-ORBProtocolFactory SSLIOP_Factory -ORBProtocolFactory IIOP_Factory" +static Resource_Factory "-ORBProtocolFactory SSLIOP_Factory" diff --git a/TAO/orbsvcs/tests/Security/mixed_security_test/server.conf.xml b/TAO/orbsvcs/tests/Security/mixed_security_test/server.conf.xml new file mode 100644 index 00000000000..e4acefdf26a --- /dev/null +++ b/TAO/orbsvcs/tests/Security/mixed_security_test/server.conf.xml @@ -0,0 +1,9 @@ +<?xml version='1.0'?> +<!-- Converted from ./orbsvcs/tests/Security/Secure_Invocation/server.conf by svcconf-convert.pl --> +<ACE_Svc_Conf> + <!-- $Id$ --> + <dynamic id="SSLIOP_Factory" type="Service_Object"> + <initializer path="TAO_SSLIOP" init="_make_TAO_SSLIOP_Protocol_Factory" params="-SSLAuthenticate SERVER_AND_CLIENT -SSLPrivateKey PEM:server_key.pem -SSLCertificate PEM:server_cert.pem"/> + </dynamic> + <static id="Resource_Factory" params="-ORBProtocolFactory SSLIOP_Factory"/> +</ACE_Svc_Conf> diff --git a/TAO/orbsvcs/tests/Security/mixed_security_test/server.cpp b/TAO/orbsvcs/tests/Security/mixed_security_test/server.cpp new file mode 100644 index 00000000000..b55a5f3a268 --- /dev/null +++ b/TAO/orbsvcs/tests/Security/mixed_security_test/server.cpp @@ -0,0 +1,218 @@ +// -*- C++ -*- + +#include <ace/SString.h> +#include <ace/ARGV.h> + +#include <orbsvcs/SecurityLevel2C.h> +#include <orbsvcs/SecurityLevel3C.h> + +#include "Foo_i.h" +#include "constants.h" + +ACE_RCSID (Secure_Invocation, + server, + "$Id$") + +/* + This tests the ability to use the SecurityManager/AccessDecision tools + to permit unsecured access to specific object references, while all other + references must be accessed via secured means. (Note that, for the purposes + of this conversation, "secured access" refers to the transport type, and + an SSLIOP transport satisfies the requirements for "secured access.") + + In order to test this, we present a modified version of the + Secure_Invocation test which creates two references of the same type + (using the same type tests that access is granted on a per-object + rather than per-type basis) and uses the AccessDecision tools to + permit unsecured access to one of them, while leaving the other + restricted only to secured access. The server then publishes each + of these IORs in different files. + + The other half is the client side. The client will operate the same + as it currently does, just performing the invocations on both IORs. + When invoking on the secured reference, the client's insecure + invocation should receive a NO_PERMISSION. However, when invoking + on the permitted reference, the insecure invocation AND the secure + invocation should both succeed. + + IMPORTANT: SSLIOP is configured without "-SSLNoProtection" in the + service configurator service listing. + */ + +// Init/setup exception +struct RirFailedException +{ + RirFailedException (const char* token = 0) : token_(token) { } + const char* token_; +}; + +template <typename REALTYPE> +typename REALTYPE::_ptr_type +rir(CORBA::ORB_ptr orb, const char* token) +{ + if (CORBA::is_nil (orb) || token == 0) + return REALTYPE::_nil(); + + CORBA::Object_var o = orb->resolve_initial_references (token); + if (CORBA::is_nil (o.in())) + throw RirFailedException (token); + + typename REALTYPE::_var_type r = REALTYPE::_narrow (o.in()); + return r._retn(); +} + +void +init_and_setup (int& argc, + char* argv[], + CORBA::ORB_var& orb, + PortableServer::POA_var& rootpoa, + PortableServer::POAManager_var& poamgr, + SecurityLevel3::SecurityCurrent_var& sl3current, + TAO::SL2::AccessDecision_var& sl2ad) +{ + orb = CORBA::ORB_init (argc, argv); + rootpoa = rir<PortableServer::POA> (orb, "RootPOA"); + poamgr = rootpoa->the_POAManager(); + + sl3current = + rir<SecurityLevel3::SecurityCurrent>(orb, "SecurityLevel3:SecurityCurrent"); + + SecurityLevel2::SecurityManager_var sl2sm = + rir<SecurityLevel2::SecurityManager> (orb, + "SecurityLevel2:SecurityManager"); + SecurityLevel2::AccessDecision_var ad = sl2sm->access_decision (); + + sl2ad = TAO::SL2::AccessDecision::_narrow (ad.in ()); + if (CORBA::is_nil (sl2ad.in ())) + throw "non-tao accessdecision"; +} + +struct IORPublicationException +{ + static const unsigned int OK = 0; + static const unsigned int BAD_PARAM = 1; + static const unsigned int IO_FAILURE = 2; + + IORPublicationException (unsigned why, int errnoval = 0) + : why_(why), errnoval_(errnoval) { } + + unsigned int why_; // one of the const values above + int errnoval_; // if set, the relevant value of errno at failure +}; + +void +publish_ior (CORBA::ORB_ptr orb, CORBA::Object_ptr o, const char* filename) +{ + if (filename == 0 || CORBA::is_nil (orb) || CORBA::is_nil (o)) + throw IORPublicationException (IORPublicationException::BAD_PARAM); + + CORBA::String_var ior = orb->object_to_string (o); + + FILE *output_file = ACE_OS::fopen (filename, "w"); + if (output_file == 0) + { + ACE_ERROR ((LM_ERROR, + "Cannot open output file %s for writing IOR\n", + filename)); + throw IORPublicationException (IORPublicationException::IO_FAILURE, + errno); + } + + ACE_OS::fprintf (output_file, "%s", ior.in() ); + ACE_OS::fclose (output_file); +} + +int +main (int argc, char *argv[]) +{ + // Necessary nonsense to make up for deficencies doing this + // in run_test.pl on Windows platforms. + ACE_TString env ("SSL_CERT_FILE="); + env += TAO_Mixed_Security_Test::cert_file; + ACE_OS::putenv (env.c_str ()); + + CORBA::ORB_var orb; + Foo_i *server1; + Foo_i *server2; + + try + { + // 1. ORB setup: init, + // grab refs for RootPOA, SL3::SecCurrent, poamgr, AccessDecision, etc. + PortableServer::POA_var rootpoa; + PortableServer::POAManager_var poamgr; + SecurityLevel3::SecurityCurrent_var sl3current; + TAO::SL2::AccessDecision_var sl2ad; + + // throws exception if it can't work + init_and_setup (argc, argv, orb, rootpoa, poamgr, sl3current, sl2ad); + ACE_DEBUG ((LM_DEBUG, "mixed_security/server: " + "init and setup complete\n")); + + // 2. Create servant #1 of Foo_i, and its associated Object + ACE_NEW_RETURN (server1, Foo_i (orb.in(), sl3current.in()), 1); + Foo::Bar_var server1_obj = server1->_this (); + ACE_DEBUG ((LM_DEBUG, "mixed_security/server: " + "created servant/object #1\n")); + + // 3. Create servant #2 of Foo_i, and its associated Object + ACE_NEW_RETURN (server2, Foo_i (orb.in(), sl3current.in()), 1); + + Foo::Bar_var server2_obj = server2->_this(); + ACE_DEBUG ((LM_DEBUG, "mixed_security/server: " + "created servant/object #2\n")); + + // 4. add servant #2's Object reference to the "permitted" list. + PortableServer::ObjectId_var oid = rootpoa->servant_to_id (server2); + CORBA::OctetSeq_var poaid = rootpoa->id(); + CORBA::String_var orbid = orb->id(); + sl2ad->add_object (orbid.in(), poaid.in(), oid.in(), true); + ACE_DEBUG ((LM_DEBUG, "mixed_security/server: " + "added object #2 as a permitted reference for " + "non-secure invocations\n")); + + // 5. publish references to #1 and #2 to distinct files + publish_ior (orb, server1_obj, + TAO_Mixed_Security_Test::restricted_ior_file); + publish_ior (orb, server2_obj, + TAO_Mixed_Security_Test::permitted_ior_file); + ACE_DEBUG ((LM_DEBUG, "mixed_security/server: " + "published IORs for objects\n")); + + // 6. activate the POA manager + poamgr->activate (); + + // 7. run the orb. + ACE_DEBUG ((LM_DEBUG, "mixed_security/server: " + "running the orb\n")); + orb->run (); + } + catch (const RirFailedException& e) + { + ACE_ERROR ((LM_ERROR, + "mixed_security/server: resolve_initial_references" + " failed for %s\n", + e.token_)); + return 1; + } + catch (const IORPublicationException& e) + { + ACE_ERROR ((LM_ERROR, + "mixed_security/server: failed to publish IOR (%s)\n", + (e.why_ == IORPublicationException::BAD_PARAM) ? "BAD_PARAM" : + (e.why_ == IORPublicationException::IO_FAILURE) ? "IO_FAILURE": + "<unknown>")); + } + catch (CORBA::Exception& ex) + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, + "Caught exception:"); + return 1; + } + + // Do I need to delete server1 and server2, or, since they're refcounted, + // will they get automatically cleaned up on POA destruction? + orb->destroy (); + + return 0; +} diff --git a/TAO/orbsvcs/tests/Security/mixed_security_test/server_cert.pem b/TAO/orbsvcs/tests/Security/mixed_security_test/server_cert.pem new file mode 100644 index 00000000000..0fc394c24d7 --- /dev/null +++ b/TAO/orbsvcs/tests/Security/mixed_security_test/server_cert.pem @@ -0,0 +1,16 @@ +-----BEGIN CERTIFICATE----- +MIICgzCCAewCAQMwDQYJKoZIhvcNAQEEBQAwgYwxCzAJBgNVBAYTAlVTMQswCQYD +VQQIEwJDQTEPMA0GA1UEBxMGSXJ2aW5lMRIwEAYDVQQKEwlET0MgR3JvdXAxEDAO +BgNVBAsWB1VDSV9ET0MxETAPBgNVBAMTCFByaXlhbmthMSYwJAYJKoZIhvcNAQkB +FhdwZ29udGxhQGRvYy5lY2UudWNpLmVkdTAeFw0wMTA2MTExNzQ4NTVaFw0xMTA2 +MDkxNzQ4NTVaMIGGMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExDzANBgNVBAcT +BklydmluZTEMMAoGA1UEChMDT0NJMRAwDgYDVQQLEwdUQU8rT0NJMREwDwYDVQQD +EwhQcml5YW5rYTEmMCQGCSqGSIb3DQEJARYXcGdvbnRsYUBkb2MuZWNlLnVjaS5l +ZHUwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANKXmudWiLVu/zdBlSr0/dlr +pRe+Ie26cPyMo5lKiYNY77tABTiOXe5qLUEryjQ/fZ74gmBe4AYFwb7nu/f58X4A +0tzSg2M4spWM7N4tzf+YbcUipRt9sEISxwfUxNNWTKnLxvCmkzOsISisukdzTkqJ +fdzEcPfhO2BZKOdmlg1hAgMBAAEwDQYJKoZIhvcNAQEEBQADgYEAjUl3ami01tPY +P1vMp2642dsIKLZis0TmeWp6HNpm52TbiGZOCqDrvtSQ9+2vGz0BkHvGqWKtD+wv +zJH23fNnqFuzy1C1xtjoeqhXECTsWVTVdoEox8hSWxPiYRE2dioraZQQ5ENDosh+ +V9YcqJJpnKDUOSGVGuyaU7DpR8yK0pc= +-----END CERTIFICATE----- diff --git a/TAO/orbsvcs/tests/Security/mixed_security_test/server_key.pem b/TAO/orbsvcs/tests/Security/mixed_security_test/server_key.pem new file mode 100644 index 00000000000..567a41da6dc --- /dev/null +++ b/TAO/orbsvcs/tests/Security/mixed_security_test/server_key.pem @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICXAIBAAKBgQDSl5rnVoi1bv83QZUq9P3Za6UXviHtunD8jKOZSomDWO+7QAU4 +jl3uai1BK8o0P32e+IJgXuAGBcG+57v3+fF+ANLc0oNjOLKVjOzeLc3/mG3FIqUb +fbBCEscH1MTTVkypy8bwppMzrCEorLpHc05KiX3cxHD34TtgWSjnZpYNYQIDAQAB +AoGAC/TxpZrjLjH8KZ3+oy6/zv1upTd1Y7MHQT+W9lgmEKAXFHGhGkHzEVtT8HRV +CbxlHIaNmH0qiQ0AoB82K/E0BdIMvE+y2qQwlpMfBMX6/TACORReJN3NXGsXwHP4 +/pNlS4LX7/NZbxlReAlDNP+FO8sdKZTyM3VXHFWJbmm4wsECQQD06zQ4uthp0zI9 +WTZiiAUgYwOcnLnXwfWOLAr8RCnYgwiS7MBCcmhZAgWX5SZJYVCwEJ12DAHy02NJ +EhiSgo+JAkEA3B7PcS5FqZFi6wVjEG6yF8OuSb/rl+FZfV6utZdCVdMPxacEVxlD +q7H/dk23O4WwASBriU0PR9/KG3T/LvKBGQJAaYRn1EUTdcxKqcmkt6CYbNKbvL59 +BqqGq4DoHrUTPjd92ybq0fXOZQKM/Fr6OsUVaTVPUYtsz3wpG1MTiRN82QJACX6+ +vggb8yuVU8QAuPW9cu769q1zsTKEVLcf3C9xKhiXppQEyOkLFT3xYh4KGGQ06meG +m/6Z+SS7KCIM2+6UCQJBANHIzgxDWtrLuWJviNh9EbCsdMioxBH+LGaqFKLC70xD +Pyoqn+QJQu/ekT+FUb0BeFJfGPzFjh1mFYn4tXxWqMs= +-----END RSA PRIVATE KEY----- diff --git a/TAO/orbsvcs/tests/Security/mixed_security_test/server_key_nopasswd.pem b/TAO/orbsvcs/tests/Security/mixed_security_test/server_key_nopasswd.pem new file mode 100644 index 00000000000..2381bdcc6df --- /dev/null +++ b/TAO/orbsvcs/tests/Security/mixed_security_test/server_key_nopasswd.pem @@ -0,0 +1,16 @@ +RSA key ok +-----BEGIN RSA PRIVATE KEY----- +MIICXgIBAAKBgQDOtfLxhcWktrjY/U9Mdsy9WaUeqFZGWkz2gknKMNrfJnKAdmuU +RaP2G9X565FhgyrEpb5bYJUC3aTLhdr5NsDFt3V1hhs9rev6WSeONmiAlOrUrKCB +cpF3K0HyU4bVp06/FgtWFUp8ja88B8zLhwak6KAGYBUQZXVtMsaJliYLNQIDAQAB +AoGAXIqghPg6j48uGhbtlXHqHysu/Ran6T8sDYAuwNI2aoiv4kshxnOW/+teVFDd ++SXb08XP/uCyVWIdEPCQI9obWppALzQhF5kALhchnlEATkVxkdx6T5PyGnFq5rpc +NCfb3Q68T5bcFvsgup9Lt8JpGBQGvjYJZYkJuMvWmH6Bc9ECQQD4TwB+p5MjRALX +lcMI8pURt6CKxpWLyFUUkQi6HksXzxeh4PDErLxsyFexKec7TOap5xnWZMPkjl76 +BdW65abrAkEA1R0XSCfu3B4LnX4zlDi+nUXG8YvquuZ21TRrNg3YmVcyF+jvkM1f +4MGRPRF3hnTuZhnlD+wEubpmpcoNnNTOXwJBAIfZOQ0SAzblC6UE42puxU2nJ+ck +1EZgeOPCoYKp9i11eJlw5mjDlGbziL59jWttHDlSHVmlUWMm3SFutcsFv7cCQQCK +i+UM5dklhOrsMpV5sQJK4IgblGi/pQBwTym79HhyB/vrC2ZjbwD77xtq5iYcZXxv +KDqAhWH1FLeS5K7A3KBlAkEAqwIhKyV1kK0EtvpNMprfIGNccRjNX8TJEQsN49EE +luhKkAam4CoA1R2wZc0VHfWqilK0qhrezXxlo4OeElxiRg== +-----END RSA PRIVATE KEY----- diff --git a/TAO/orbsvcs/tests/Security/mixed_security_test/server_none.conf b/TAO/orbsvcs/tests/Security/mixed_security_test/server_none.conf new file mode 100644 index 00000000000..e445c19615f --- /dev/null +++ b/TAO/orbsvcs/tests/Security/mixed_security_test/server_none.conf @@ -0,0 +1,4 @@ +# $Id$ + +dynamic SSLIOP_Factory Service_Object * TAO_SSLIOP:_make_TAO_SSLIOP_Protocol_Factory() "-SSLAuthenticate NONE -SSLPrivateKey PEM:server_key.pem -SSLCertificate PEM:server_cert.pem" +static Resource_Factory "-ORBProtocolFactory SSLIOP_Factory" diff --git a/TAO/orbsvcs/tests/Security/mixed_security_test/server_none.conf.xml b/TAO/orbsvcs/tests/Security/mixed_security_test/server_none.conf.xml new file mode 100644 index 00000000000..2b61ce1d547 --- /dev/null +++ b/TAO/orbsvcs/tests/Security/mixed_security_test/server_none.conf.xml @@ -0,0 +1,9 @@ +<?xml version='1.0'?> +<!-- Converted from ./orbsvcs/tests/Security/Secure_Invocation/server_none.conf by svcconf-convert.pl --> +<ACE_Svc_Conf> + <!-- $Id$ --> + <dynamic id="SSLIOP_Factory" type="Service_Object"> + <initializer path="TAO_SSLIOP" init="_make_TAO_SSLIOP_Protocol_Factory" params="-SSLAuthenticate NONE -SSLPrivateKey PEM:server_key.pem -SSLCertificate PEM:server_cert.pem"/> + </dynamic> + <static id="Resource_Factory" params="-ORBProtocolFactory SSLIOP_Factory"/> +</ACE_Svc_Conf> diff --git a/TAO/orbsvcs/tests/Security/mixed_security_test/server_nopasswd.conf b/TAO/orbsvcs/tests/Security/mixed_security_test/server_nopasswd.conf new file mode 100644 index 00000000000..19cd88ba742 --- /dev/null +++ b/TAO/orbsvcs/tests/Security/mixed_security_test/server_nopasswd.conf @@ -0,0 +1,4 @@ +# $Id$ + +dynamic SSLIOP_Factory Service_Object * TAO_SSLIOP:_make_TAO_SSLIOP_Protocol_Factory() "-SSLAuthenticate NONE -SSLPrivateKey PEM:server_key_nopasswd.pem -SSLCertificate PEM:server_cert.pem" +static Resource_Factory "-ORBProtocolFactory SSLIOP_Factory" diff --git a/TAO/orbsvcs/tests/Security/mixed_security_test/server_nopasswd.conf.xml b/TAO/orbsvcs/tests/Security/mixed_security_test/server_nopasswd.conf.xml new file mode 100644 index 00000000000..0b53b803d90 --- /dev/null +++ b/TAO/orbsvcs/tests/Security/mixed_security_test/server_nopasswd.conf.xml @@ -0,0 +1,9 @@ +<?xml version='1.0'?> +<!-- Converted from ./orbsvcs/tests/Security/Secure_Invocation/server_nopasswd.conf by svcconf-convert.pl --> +<ACE_Svc_Conf> + <!-- $Id$ --> + <dynamic id="SSLIOP_Factory" type="Service_Object"> + <initializer path="TAO_SSLIOP" init="_make_TAO_SSLIOP_Protocol_Factory" params="-SSLAuthenticate NONE -SSLPrivateKey PEM:server_key_nopasswd.pem -SSLCertificate PEM:server_cert.pem"/> + </dynamic> + <static id="Resource_Factory" params="-ORBProtocolFactory SSLIOP_Factory"/> +</ACE_Svc_Conf> diff --git a/TAO/tao/CDR.cpp b/TAO/tao/CDR.cpp index 58d7524f7ba..7ef61eb4840 100644 --- a/TAO/tao/CDR.cpp +++ b/TAO/tao/CDR.cpp @@ -78,6 +78,14 @@ TAO_OutputCDR::TAO_OutputCDR (size_t size, , timeout_ (0) { ACE_FUNCTION_TIMEPROBE (TAO_OUTPUT_CDR_CTOR1_ENTER); + +#if defined (TAO_ZERO_TAO_OUTPUTCDR_ALLOCATED_BUFFERS) + // Zero out the buffer if we allocated the buffer. + if (size == 0) + (void) ACE_OS::memset (this->current()->wr_ptr(), + 0, + this->current()->space()); +#endif /* TAO_ZERO_TAO_OUTPUTCDR_ALLOCATED_BUFFERS */ } TAO_OutputCDR::TAO_OutputCDR (char *data, diff --git a/TAO/tao/Profile.cpp b/TAO/tao/Profile.cpp index cbed29337e1..37037ebefe1 100644 --- a/TAO/tao/Profile.cpp +++ b/TAO/tao/Profile.cpp @@ -154,6 +154,13 @@ TAO_Profile::encode (TAO_OutputCDR &stream) const TAO_DEF_GIOP_MAJOR, TAO_DEF_GIOP_MINOR); +#if defined (TAO_ZERO_TAO_OUTPUTCDR_ALLOCATED_BUFFERS) + // Support limited oref ACE_OS::strcmp + (void) ACE_OS::memset (encap.current()->wr_ptr (), + 0, + encap.current()->space ()); +#endif /* TAO_ZERO_TAO_OUTPUTCDR_ALLOCATED_BUFFERS */ + // Create the profile body this->create_profile_body (encap); diff --git a/TAO/tests/objref_comparison_test/foo.idl b/TAO/tests/objref_comparison_test/foo.idl new file mode 100644 index 00000000000..11ecffcf4c4 --- /dev/null +++ b/TAO/tests/objref_comparison_test/foo.idl @@ -0,0 +1,3 @@ +interface foo { + boolean match_references (); +}; diff --git a/TAO/tests/objref_comparison_test/main.cpp b/TAO/tests/objref_comparison_test/main.cpp new file mode 100644 index 00000000000..39245167a57 --- /dev/null +++ b/TAO/tests/objref_comparison_test/main.cpp @@ -0,0 +1,145 @@ +#include <iostream> +#include <fstream> +#include <tao/corba.h> +#include <ace/Functor.h> +#include <ace/Task.h> +#include "fooS.h" + +/* + This isn't too complicated, but it is a little convoluted. So, here's the + explanation: + + 1. Two threads. One thread is a CORBA server, the other a CORBA + client to that CORBA server. + + 2. the main thread sets up the server-side stuff, and then fires off + a task to run the server. + + 3. once the server thread/task is running, the main thread makes + invocations to "match_references()" and reports the outcome. + + The CORBA Object compares the stringified representation of two IORs + both generated from the ORB but in different contexts, and returns the + result of the comparison as a boolean. + */ + +class Foo_Impl : public virtual POA_foo +{ +public: + CORBA::Boolean match_references (); + + CORBA::String_var ior_from_main_; + ACE_Equal_To<const char*> equal_func; + ACE_Hash<const char*> hash_func; +}; + +CORBA::Boolean +Foo_Impl::match_references () +{ + CORBA::Object_var o = _this (); + CORBA::ORB_var orb = o->_get_orb (); + CORBA::String_var ior_from_upcall = orb->object_to_string (o); + + CORBA::Boolean r1 = equal_func (this->ior_from_main_.in(), ior_from_upcall.in()); +#if 0 + if (! r1) + { + std::ofstream f1("ior_from_main", std::ios::app); + f1 << ior_from_main_.in() << std::endl; + + std::ofstream f2("ior_from_upcall", std::ios::app); + f2 << ior_from_upcall.in() << std::endl; + } +#endif + + return r1; +} + +class Server_Task : public ACE_Task_Base +{ +public: + Server_Task (CORBA::ORB_ptr orb) + : orb_ (CORBA::ORB::_duplicate (orb)) + { + } + virtual ~Server_Task (); + + virtual int svc (); +private: + CORBA::ORB_var orb_; +}; + +Server_Task::~Server_Task() { } + +int +Server_Task::svc () +{ + this->orb_->run (); + return 0; +} + +int +main (int argc, char * argv[]) +{ + CORBA::ORB_var s_orb; + try + { + s_orb = CORBA::ORB_init (argc, argv); + + CORBA::Object_var o = s_orb->resolve_initial_references ("RootPOA"); + PortableServer::POA_var rootpoa = PortableServer::POA::_narrow (o.in()); + if (CORBA::is_nil (rootpoa.in())) + ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t): failed to get root poa\n"), 1); + + PortableServer::POAManager_var poamgr = rootpoa->the_POAManager(); + + Foo_Impl* foo = 0; + ACE_NEW_RETURN (foo, Foo_Impl, 1); + PortableServer::ServantBase_var owner_transfer (foo); + PortableServer::ObjectId_var id = rootpoa->activate_object (foo); + o = rootpoa->id_to_reference (id.in()); + + Foo_Impl* foo2 = 0; + ACE_NEW_RETURN (foo2, Foo_Impl, 1); + PortableServer::ServantBase_var foo_owner (foo2); + foo_var f2 = foo2->_this (); // implicit activation + + poamgr->activate (); + + foo->ior_from_main_ = s_orb->object_to_string (o.in()); + foo2->ior_from_main_ = foo->ior_from_main_; + + Server_Task server(s_orb.in()); + server.activate(1); // activate one thread running the task + + foo_var f = foo::_narrow (o.in()); // ignore the possibility that + // it's not a 'foo' since we + // created it above + + int const iterations = 10; + ACE_DEBUG ((LM_DEBUG, "(%P|%t) client: next %d iterations should match\n", + iterations)); + for (int i = 0; i < iterations; ++i) + { + CORBA::Boolean b = f->match_references (); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) client: iteration %d, match = %d\n", + i, b)); + } + + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) client: next %d iterations should NOT match\n", + iterations)); + for (int i = 0; i < iterations; ++i) + { + CORBA::Boolean b = f2->match_references (); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) client: iteration %d, match = %d\n", + i, b)); + } + + } + catch (...) + { + } + + return 0; +} diff --git a/TAO/tests/objref_comparison_test/objref_comparison_test.mpc b/TAO/tests/objref_comparison_test/objref_comparison_test.mpc new file mode 100644 index 00000000000..23690b2be8c --- /dev/null +++ b/TAO/tests/objref_comparison_test/objref_comparison_test.mpc @@ -0,0 +1,5 @@ +project : taoserver { + Source_Files { + main.cpp + } +} diff --git a/TAO/tests/objref_comparison_test/server.conf b/TAO/tests/objref_comparison_test/server.conf new file mode 100644 index 00000000000..e178933feb9 --- /dev/null +++ b/TAO/tests/objref_comparison_test/server.conf @@ -0,0 +1,4 @@ +# $Id$ + +dynamic SSLIOP_Factory Service_Object * TAO_SSLIOP:_make_TAO_SSLIOP_Protocol_Factory() "-SSLAuthenticate SERVER_AND_CLIENT -SSLPrivateKey PEM:server_key.pem -SSLCertificate PEM:server_cert.pem -SSLNoProtection" +static Resource_Factory "-ORBProtocolFactory SSLIOP_Factory" diff --git a/TAO/tests/objref_comparison_test/server_cert.pem b/TAO/tests/objref_comparison_test/server_cert.pem new file mode 100644 index 00000000000..0fc394c24d7 --- /dev/null +++ b/TAO/tests/objref_comparison_test/server_cert.pem @@ -0,0 +1,16 @@ +-----BEGIN CERTIFICATE----- +MIICgzCCAewCAQMwDQYJKoZIhvcNAQEEBQAwgYwxCzAJBgNVBAYTAlVTMQswCQYD +VQQIEwJDQTEPMA0GA1UEBxMGSXJ2aW5lMRIwEAYDVQQKEwlET0MgR3JvdXAxEDAO +BgNVBAsWB1VDSV9ET0MxETAPBgNVBAMTCFByaXlhbmthMSYwJAYJKoZIhvcNAQkB +FhdwZ29udGxhQGRvYy5lY2UudWNpLmVkdTAeFw0wMTA2MTExNzQ4NTVaFw0xMTA2 +MDkxNzQ4NTVaMIGGMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExDzANBgNVBAcT +BklydmluZTEMMAoGA1UEChMDT0NJMRAwDgYDVQQLEwdUQU8rT0NJMREwDwYDVQQD +EwhQcml5YW5rYTEmMCQGCSqGSIb3DQEJARYXcGdvbnRsYUBkb2MuZWNlLnVjaS5l +ZHUwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANKXmudWiLVu/zdBlSr0/dlr +pRe+Ie26cPyMo5lKiYNY77tABTiOXe5qLUEryjQ/fZ74gmBe4AYFwb7nu/f58X4A +0tzSg2M4spWM7N4tzf+YbcUipRt9sEISxwfUxNNWTKnLxvCmkzOsISisukdzTkqJ +fdzEcPfhO2BZKOdmlg1hAgMBAAEwDQYJKoZIhvcNAQEEBQADgYEAjUl3ami01tPY +P1vMp2642dsIKLZis0TmeWp6HNpm52TbiGZOCqDrvtSQ9+2vGz0BkHvGqWKtD+wv +zJH23fNnqFuzy1C1xtjoeqhXECTsWVTVdoEox8hSWxPiYRE2dioraZQQ5ENDosh+ +V9YcqJJpnKDUOSGVGuyaU7DpR8yK0pc= +-----END CERTIFICATE----- diff --git a/TAO/tests/objref_comparison_test/server_key.pem b/TAO/tests/objref_comparison_test/server_key.pem new file mode 100644 index 00000000000..567a41da6dc --- /dev/null +++ b/TAO/tests/objref_comparison_test/server_key.pem @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICXAIBAAKBgQDSl5rnVoi1bv83QZUq9P3Za6UXviHtunD8jKOZSomDWO+7QAU4 +jl3uai1BK8o0P32e+IJgXuAGBcG+57v3+fF+ANLc0oNjOLKVjOzeLc3/mG3FIqUb +fbBCEscH1MTTVkypy8bwppMzrCEorLpHc05KiX3cxHD34TtgWSjnZpYNYQIDAQAB +AoGAC/TxpZrjLjH8KZ3+oy6/zv1upTd1Y7MHQT+W9lgmEKAXFHGhGkHzEVtT8HRV +CbxlHIaNmH0qiQ0AoB82K/E0BdIMvE+y2qQwlpMfBMX6/TACORReJN3NXGsXwHP4 +/pNlS4LX7/NZbxlReAlDNP+FO8sdKZTyM3VXHFWJbmm4wsECQQD06zQ4uthp0zI9 +WTZiiAUgYwOcnLnXwfWOLAr8RCnYgwiS7MBCcmhZAgWX5SZJYVCwEJ12DAHy02NJ +EhiSgo+JAkEA3B7PcS5FqZFi6wVjEG6yF8OuSb/rl+FZfV6utZdCVdMPxacEVxlD +q7H/dk23O4WwASBriU0PR9/KG3T/LvKBGQJAaYRn1EUTdcxKqcmkt6CYbNKbvL59 +BqqGq4DoHrUTPjd92ybq0fXOZQKM/Fr6OsUVaTVPUYtsz3wpG1MTiRN82QJACX6+ +vggb8yuVU8QAuPW9cu769q1zsTKEVLcf3C9xKhiXppQEyOkLFT3xYh4KGGQ06meG +m/6Z+SS7KCIM2+6UCQJBANHIzgxDWtrLuWJviNh9EbCsdMioxBH+LGaqFKLC70xD +Pyoqn+QJQu/ekT+FUb0BeFJfGPzFjh1mFYn4tXxWqMs= +-----END RSA PRIVATE KEY----- diff --git a/TAO/utils/catior/catior.cpp b/TAO/utils/catior/catior.cpp index 05ae0c0a15e..1dec96f7a7e 100644 --- a/TAO/utils/catior/catior.cpp +++ b/TAO/utils/catior/catior.cpp @@ -1204,6 +1204,92 @@ cat_tag_policies (TAO_InputCDR& stream) { } CORBA::Boolean +cat_security_association (const CORBA::UShort& a) { + // Copied from Security.idl + typedef CORBA::UShort AssociationOptions; + const AssociationOptions NoProtection = 1; + const AssociationOptions Integrity = 2; + const AssociationOptions Confidentiality = 4; + const AssociationOptions DetectReplay = 8; + const AssociationOptions DetectMisordering = 16; + const AssociationOptions EstablishTrustInTarget = 32; + const AssociationOptions EstablishTrustInClient = 64; + const AssociationOptions NoDelegation = 128; + const AssociationOptions SimpleDelegation = 256; + const AssociationOptions CompositeDelegation = 512; + +#define CHECK_PRINT(X) \ + if (a & X) ACE_DEBUG ((LM_DEBUG, "%I" #X "\n")) + + CHECK_PRINT(NoProtection); + CHECK_PRINT(Integrity); + CHECK_PRINT(Confidentiality); + CHECK_PRINT(DetectReplay); + CHECK_PRINT(DetectMisordering); + CHECK_PRINT(EstablishTrustInTarget); + CHECK_PRINT(EstablishTrustInClient); + CHECK_PRINT(NoDelegation); + CHECK_PRINT(SimpleDelegation); + CHECK_PRINT(CompositeDelegation); + + return 0; +} + +CORBA::Boolean +cat_tag_ssl_sec_trans (TAO_InputCDR& cdr) { + /* + Decode the following from the stream (copied from SSLIOP.idl) + + module Security { + typedef unsigned short AssociationOptions; + }; + ... + module SSLIOP { + struct SSL { + Security::AssociationOptions target_supports; + Security::AssociationOptions target_requires; + unsigned short port; + }; + }; + + We duplicate the code here because we do not want the catior + utility to be dependent upon SSLIOP. + */ + + CORBA::ULong length = 0; + if (cdr.read_ulong (length) == 0) + return false; + + TAO_InputCDR stream (cdr, length); + cdr.skip_bytes(length); + + CORBA::UShort target_supports; + CORBA::UShort target_requires; + CORBA::UShort port; + + if (stream.read_ushort(target_supports) == 0) + return false; + + if (stream.read_ushort(target_requires) == 0) + return false; + + if (stream.read_ushort(port) == 0) + return false; + + ACE_DEBUG ((LM_DEBUG, "%Iport = %d\n", port)); + ACE_DEBUG ((LM_DEBUG, "%Itarget_supports = 0x%x\n", target_supports)); + ACE_DEBUG ((LM_DEBUG, "%{")); + cat_security_association(target_supports); + ACE_DEBUG ((LM_DEBUG, "%}")); + ACE_DEBUG ((LM_DEBUG, "%Itarget_requires = 0x%x\n", target_requires)); + ACE_DEBUG ((LM_DEBUG, "%{")); + cat_security_association(target_requires); + ACE_DEBUG ((LM_DEBUG, "%}")); + + return true; +} + +CORBA::Boolean cat_octet_seq (const char *object_name, TAO_InputCDR& stream) { @@ -1424,6 +1510,11 @@ cat_tagged_components (TAO_InputCDR& stream) ACE_DEBUG ((LM_DEBUG, "%{%{")); cat_tag_policies(stream); ACE_DEBUG ((LM_DEBUG, "%}%}")); + } else if (tag == 20U /* SSLIOP::TAG_SSL_SEC_TRANS */) { + ACE_DEBUG ((LM_DEBUG,"%d (TAG_SSL_SEC_TRANS)\n", tag)); + ACE_DEBUG ((LM_DEBUG, "%{")); + cat_tag_ssl_sec_trans(stream); + ACE_DEBUG ((LM_DEBUG, "%}")); } else { ACE_DEBUG ((LM_DEBUG,"%d\n", tag)); ACE_DEBUG ((LM_DEBUG, "%{%{")); |