summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Cleeland <chris.cleeland@gmail.com>2007-04-03 19:37:44 +0000
committerChris Cleeland <chris.cleeland@gmail.com>2007-04-03 19:37:44 +0000
commit781d35d7fb08201a8a23b0756c69bf00c0e3ee67 (patch)
treeb9010cffc74a15f7d467223a28448a2397cf9b2d
parent6effa16ea8dfbb4a1aaefb7e1b9fab3ef356b5ab (diff)
downloadATCD-oci_mixed_security.tar.gz
Committing changes thus far in preparation to migrate them to the newoci_mixed_security
oci_mixed_security_2 branch.
-rw-r--r--TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_Invocation_Interceptor.cpp285
-rw-r--r--TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_Invocation_Interceptor.h22
-rw-r--r--TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_ORBInitializer.cpp32
-rw-r--r--TAO/orbsvcs/orbsvcs/Security/SL2_SecurityManager.cpp259
-rw-r--r--TAO/orbsvcs/orbsvcs/Security/SL2_SecurityManager.h206
-rw-r--r--TAO/orbsvcs/orbsvcs/Security/Security_ORBInitializer.cpp74
-rw-r--r--TAO/orbsvcs/orbsvcs/SecurityLevel2.idl19
7 files changed, 822 insertions, 75 deletions
diff --git a/TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_Invocation_Interceptor.cpp b/TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_Invocation_Interceptor.cpp
index 5ce2d53c82c..57bedb1ed32 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,49 @@ 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?
+ }
+
+ obj = info->resolve_initial_references ("POACurrent");
+ this->poa_current_ = PortableServer::Current::_narrow (obj.in ());
}
TAO::SSLIOP::Server_Invocation_Interceptor::~Server_Invocation_Interceptor (
@@ -30,6 +69,7 @@ TAO::SSLIOP::Server_Invocation_Interceptor::~Server_Invocation_Interceptor (
{
}
+
char *
TAO::SSLIOP::Server_Invocation_Interceptor::name ()
ACE_THROW_SPEC ((CORBA::SystemException))
@@ -46,10 +86,43 @@ TAO::SSLIOP::Server_Invocation_Interceptor::destroy ()
void
TAO::SSLIOP::Server_Invocation_Interceptor::receive_request_service_contexts (
- PortableInterceptor::ServerRequestInfo_ptr /*ri*/)
+ PortableInterceptor::ServerRequestInfo_ptr /* ri */)
+ ACE_THROW_SPEC ((CORBA::SystemException,
+ PortableInterceptor::ForwardRequest))
+{
+#if 1
+ // This operation is where the old security implementation used to
+ // makes its simplistic decision whether to permit or deny, but with
+ // the introduction of more detailed checking, there's a need to
+ // have access to information that's not available until later in
+ // the PI flow. So, it's now all moved into receive_request().
+
+
+ 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
+ // (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)
+ throw CORBA::NO_PERMISSION ();
+#endif
+}
+
+
+void
+TAO::SSLIOP::Server_Invocation_Interceptor::receive_request (
+ PortableInterceptor::ServerRequestInfo_ptr ri)
ACE_THROW_SPEC ((CORBA::SystemException,
PortableInterceptor::ForwardRequest))
{
+#if 0
// 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.
@@ -59,14 +132,192 @@ TAO::SSLIOP::Server_Invocation_Interceptor::receive_request_service_contexts (
// 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 1
+ /*
+ // Of course, since we're implementing a SecurityManager, we can do
+ // this now! But we want to keep the default behavior, too...
- if (no_ssl && this->qop_ != ::Security::SecQOPNoProtection)
- throw CORBA::NO_PERMISSION ();
+ Q: It's also not clear how we're supposed to query the securitymanager
+ "for the current object's SecureInvocationPolicy". Maybe we need to
+ query the policies on the object itself? Maybe we can ask the
+ ServerRequestInfo via get_server_policy()?
+
+ A: The spec says that "This operation returns the policy in effect
+ for this operation for the given policy type. The returned
+ CORBA::Policy object shall only be a policy whose type was
+ registered via register_policy_factory()", so that should give us
+ what we want.
+ */
+
+ SecurityLevel2::AccessDecision_var ad =
+ this->sec2manager_->access_decision ();
+
+
+ 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
+ // (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)
+#if 0
+ throw CORBA::NO_PERMISSION ();
+ if ( ! CORBA:is_nil (ad.in ())
+ && ri->get_server_policy(SecureInvocationPolicy) == SecTargetSecureInvocationPolicy)
+#endif
+ {
+ /*
+ * 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
+
+ /* Get the target object */
+ CORBA::Object_var target = CORBA::Object::_nil ();
+
+#if 0 // we want to use the POACurrent::get_reference()!
+ // I suppose that we can derive this using server_id, adapter_id
+ // and object_id using id_to_reference. One problem is that,
+ // according to the spec, id_to_reference() can only be used
+ // when the POA in question has the RETAIN policy so this would
+ // be unavailable when the POA has NO_RETAIN.
+ try {
+ int no_args = 0;
+ CORBA::ORB_var orb = CORBA::ORB_init (no_args, 0, ri->orb_id());
+ CORBA::Object_var obj = orb->resolve_initial_references ("RootPOA");
+ PortableServer::POA_var rootpoa =
+ PortableServer::POA::_narrow (obj.in ());
+ if (CORBA::is_nil (rootpoa.in ()))
+ // Probably not a good choice for exception, but we need to
+ // throw something.
+ throw PortableServer::POA::AdapterNonExistent();
+
+ // @@CJC Grrr...of course nothing is ever easy. What we'd really
+ // like to be able to do is something like...
+ // rootpoa->find_POA (ri->adapter_id (), false); // don't activate
+ // to get a reference to the POA indicated here. Sigh. CORBA 3.0
+ // provides adapter_name(), so maybe I'll get lucky and that'll be
+ // available. Otherwise, I'm going to have to resort to ugliness
+ // and proprietary hacks to get this info, b/c adapter_id()
+ // returns an opaque octet sequence.
+ //
+ // The good news is that adapter_name() exists, but it doesn't
+ // return a name suitable for submission to find_POA(). Rather,
+ // it returns a string sequence. Exactly what's in that sequence
+ // we don't know, but I'll guess that it's supposed to be an in-order
+ // list of the poa path down to the poa that's hosting the target
+ // CORBA Object. So, if we look at the last element in the sequence
+ // we should get the name of the hosting POA. <fingers crossed>
+ PortableInterceptor::AdapterName_var poa_path = ri->adapter_name ();
+ size_t last_component_index = poa_path->length() - 1;
+
+ const char* last_component = poa_path[last_component_index];
+ PortableServer::POA_var poa =
+ rootpoa->find_POA (last_component,
+ false); // don't activate
+
+ // Yow. Sometimes the C++ mapping mystifies me in its oddities.
+ // One would expect that, since the requestinfo has an ObjectId
+ // attribute, and the id_to_reference() operation takes an ObjectId
+ // as an "in" argument, that one could simply do
+ // target = poa->id_to_reference (ri->object_id())
+ // Alas, 'tis not that simple. The mapping for a return value for
+ // an unbounded sequence is T*, and the mapping for an "in" is
+ // const T&, which means that we have to dereference the pointer.
+ //
+ // Damn, that's really ugly. But I'm glad that's off my chest.
+ target = poa->id_to_reference (*(ri->object_id ()));
+ }
+#define quote(x) #x
+ catch (const PortableServer::POA::ObjectNotActive& e) {
+ // thrown by id_to_reference()
+ e._tao_print_exception ("ssliop_invocation_interceptor::receive_request @ " quote(__LINE__));
+ }
+ catch (const PortableServer::POA::WrongPolicy& e) {
+ // thrown by id_to_reference()
+ e._tao_print_exception ("ssliop_invocation_interceptor::receive_request @ " quote(__LINE__));
+ }
+ catch (const PortableServer::POA::AdapterNonExistent& e) {
+ // thrown by find_POA()
+ e._tao_print_exception ("yoyoyo ssliop_invocation_interceptor::receive_request @ " quote(__LINE__));
+ }
+ catch (const CORBA::ORB::InvalidName& e) {
+ // thrown by resolve_initial_references()
+ e._tao_print_exception ("ssliop_invocation_interceptor::receive_request @ " quote(__LINE__));
+ }
+#else
+ target = this->poa_current_->get_reference ();
+#endif
+
+ char* operation_name = ri->operation ();
+ char* target_interface_name = ri->target_most_derived_interface(); // is this the repository ID?
+
+ CORBA::Boolean it_should_happen = false;
+ if (ad)
+ it_should_happen = ad->access_allowed (cred_list,
+ target.in(),
+ operation_name,
+ target_interface_name);
+ else
+ it_should_happen = true; // if no access_decision, then let it all through
+
+ if (! it_should_happen)
+ {
+ throw CORBA::NO_PERMISSION ();
+ }
+ }
+ else
+#endif
+ {
+ // PREVIOUS DEFAULT BEHAVIOR
+
+ 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
+ // (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)
+ throw CORBA::NO_PERMISSION ();
+ }
#if defined(DEBUG_PEER_CERTIFICATES)
try
@@ -126,15 +377,7 @@ TAO::SSLIOP::Server_Invocation_Interceptor::receive_request_service_contexts (
throw CORBA::NO_PERMISSION ();
}
#endif /* DEBUG_PEER_CERTIFICATES */
-}
-
-
-void
-TAO::SSLIOP::Server_Invocation_Interceptor::receive_request (
- PortableInterceptor::ServerRequestInfo_ptr /* ri */)
- ACE_THROW_SPEC ((CORBA::SystemException,
- PortableInterceptor::ForwardRequest))
-{
+#endif
}
void
diff --git a/TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_Invocation_Interceptor.h b/TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_Invocation_Interceptor.h
index e382a2042a2..2ae6d0bc9a7 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
@@ -124,9 +134,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 102fbeb2246..faccc92f0f1 100644
--- a/TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_ORBInitializer.cpp
+++ b/TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_ORBInitializer.cpp
@@ -88,35 +88,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)
- {
- const size_t 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,
@@ -161,7 +140,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..bdef351d9cd
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/Security/SL2_SecurityManager.cpp
@@ -0,0 +1,259 @@
+// $Id$
+
+#include "orbsvcs/Security/SL2_SecurityManager.h"
+
+#include "tao/ORB_Constants.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 ()
+ ACE_THROW_SPEC ((CORBA::SystemException))
+{
+ throw CORBA::NO_IMPLEMENT ();
+}
+
+SecurityLevel2::CredentialsList*
+TAO::Security::SecurityManager::own_credentials ()
+ ACE_THROW_SPEC ((CORBA::SystemException))
+{
+ throw CORBA::NO_IMPLEMENT ();
+}
+
+SecurityLevel2::RequiredRights_ptr
+TAO::Security::SecurityManager::required_rights_object ()
+ ACE_THROW_SPEC ((CORBA::SystemException))
+{
+ throw CORBA::NO_IMPLEMENT ();
+}
+
+SecurityLevel2::PrincipalAuthenticator_ptr
+TAO::Security::SecurityManager::principal_authenticator ()
+ ACE_THROW_SPEC ((CORBA::SystemException))
+{
+ return SecurityLevel2::PrincipalAuthenticator::_duplicate
+ (this->principal_authenticator_.in () );
+}
+
+SecurityLevel2::AccessDecision_ptr
+TAO::Security::SecurityManager::access_decision ()
+ ACE_THROW_SPEC ((CORBA::SystemException))
+{
+ return SecurityLevel2::AccessDecision::_duplicate (this->access_decision_.in () );
+}
+
+SecurityLevel2::AuditDecision_ptr
+TAO::Security::SecurityManager::audit_decision ()
+ ACE_THROW_SPEC ((CORBA::SystemException))
+{
+ throw CORBA::NO_IMPLEMENT ();
+}
+
+SecurityLevel2::TargetCredentials_ptr
+TAO::Security::SecurityManager::get_target_credentials (CORBA::Object_ptr /*o*/)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+{
+ throw CORBA::NO_IMPLEMENT ();
+}
+
+void
+TAO::Security::SecurityManager::remove_own_credentials (
+ SecurityLevel2::Credentials_ptr creds)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+{
+ throw CORBA::NO_IMPLEMENT ();
+}
+
+CORBA::Policy_ptr
+TAO::Security::SecurityManager::get_security_policy (CORBA::PolicyType policy_type)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+{
+ throw CORBA::NO_IMPLEMENT ();
+}
+
+/*
+ * AccessDecision stuff below here
+ */
+
+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)
+{
+ // Originally this lived in access_allowed, but it was needed
+ // in add_object and remove_object, too, so it's been factored out.
+ //
+ // We need an ORB reference here. Where do we get it?
+ //
+ // The primary place we need this facility is in access_allowed.
+ // Unfortunately, the interface for access_allowed is cast in
+ // dormant OMG spec stone, so that can't change. We could pass in a
+ // reference as an argument to the constructor and store it, but
+ // what do we do, then, if the same interceptor is registered with
+ // multiple ORBs (is that possible?!?!)? Then we could end up using
+ // a different ORB to stringify, which could end up giving us a
+ // different string, which means they won't compare propertly.
+ //
+ // As a hack, we could realize that TAO's CORBA::Object implementation
+ // has a reference to its associated ORB, and just dip in there
+ // to get access to it. Ugly, but at least it should probably work.
+ CORBA::ORB_var orb = obj->_get_orb ();
+ CORBA::String_var ior = orb->object_to_string (obj);
+ return ior;
+}
+
+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
+ )
+ ACE_THROW_SPEC ((CORBA::SystemException))
+{
+ // @@ 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);
+
+ // LOCK THE MAP!
+ ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, guard, this->map_lock_,
+ this->default_allowance_decision_);
+
+ // 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_;
+ }
+
+ // For now we just return the default.
+ return access_decision;
+}
+
+void
+TAO::Security::AccessDecision::add_object (CORBA::Object_ptr obj,
+ CORBA::Boolean allow_insecure_access)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+{
+ // make a key from 'obj'
+ OBJECT_KEY key = this->map_key_from_objref (obj);
+
+ // bind it into the access_map_, replacing anything that's there.
+ // LOCK THE MAP!
+ ACE_GUARD (TAO_SYNCH_MUTEX, guard, this->map_lock_);
+
+ // 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(%s,%d) "
+ "unexpectedly failed (errno=%d)\n",
+ (const char*)key,
+ allow_insecure_access,
+ errno));
+ throw
+ CORBA::NO_MEMORY(CORBA::SystemException::_tao_minor_code (TAO::VMCID,
+ errno),
+ CORBA::COMPLETED_NO);
+ }
+}
+
+void
+TAO::Security::AccessDecision::remove_object (CORBA::Object_ptr obj)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+{
+ // make a key from 'obj'
+ OBJECT_KEY key = this->map_key_from_objref (obj);
+
+ // 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 >= 5)
+ ACE_DEBUG ((LM_DEBUG,
+ "TAO (%P|%t): SL2_AccessDecision::remove_object(%s) "
+ "object not found in access map\n",
+ (const char*)key));
+ }
+ else
+ {
+ if (TAO_debug_level > 0)
+ ACE_DEBUG ((LM_DEBUG,
+ "TAO (%P|%t): SL2_AccessDecision::remove_object(%s) "
+ " unexpected error during unbind from map (errno=%d\n)",
+ (const char*)key,
+ errno));
+ throw
+ CORBA::UNKNOWN (CORBA::SystemException::_tao_minor_code (TAO::VMCID,
+ errno),
+ CORBA::COMPLETED_NO);
+ }
+ }
+}
+
+CORBA::Boolean
+TAO::Security::AccessDecision::default_decision (void)
+ ACE_THROW_SPEC ((::CORBA::SystemException))
+{
+ return this->default_allowance_decision_;
+}
+
+void
+TAO::Security::AccessDecision::default_decision (CORBA::Boolean d)
+ ACE_THROW_SPEC ((::CORBA::SystemException))
+{
+ 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..66af6656715
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/Security/SL2_SecurityManager.h
@@ -0,0 +1,206 @@
+// -*- 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 "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
+ )
+ ACE_THROW_SPEC ((::CORBA::SystemException));
+
+ virtual ::CORBA::Boolean default_decision (void)
+ ACE_THROW_SPEC ((::CORBA::SystemException));
+ virtual void default_decision (::CORBA::Boolean d)
+ ACE_THROW_SPEC ((::CORBA::SystemException));
+
+ virtual void add_object (::CORBA::Object_ptr obj,
+ ::CORBA::Boolean allow_insecure_access)
+ ACE_THROW_SPEC ((::CORBA::SystemException));
+ virtual void remove_object (::CORBA::Object_ptr obj)
+ ACE_THROW_SPEC ((::CORBA::SystemException));
+
+ 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.
+ typedef CORBA::String_var 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, // stringified IOR
+ CORBA::Boolean, // access_allowed?
+ ACE_Hash<const char*>,
+ ACE_Equal_To<const char*>,
+ 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);
+ };
+
+ /**
+ * @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 ()
+ ACE_THROW_SPEC ((CORBA::SystemException));
+ virtual SecurityLevel2::CredentialsList* own_credentials ()
+ ACE_THROW_SPEC ((CORBA::SystemException));
+ virtual SecurityLevel2::RequiredRights_ptr required_rights_object ()
+ ACE_THROW_SPEC ((CORBA::SystemException));
+ virtual SecurityLevel2::PrincipalAuthenticator_ptr principal_authenticator ()
+ ACE_THROW_SPEC ((CORBA::SystemException));
+ virtual SecurityLevel2::AccessDecision_ptr access_decision ()
+ ACE_THROW_SPEC ((CORBA::SystemException));
+ virtual SecurityLevel2::AuditDecision_ptr audit_decision ()
+ ACE_THROW_SPEC ((CORBA::SystemException));
+ virtual SecurityLevel2::TargetCredentials_ptr get_target_credentials (CORBA::Object_ptr o)
+ ACE_THROW_SPEC ((CORBA::SystemException));
+ virtual void remove_own_credentials (SecurityLevel2::Credentials_ptr creds)
+ ACE_THROW_SPEC ((CORBA::SystemException));
+ virtual CORBA::Policy_ptr get_security_policy (CORBA::PolicyType policy_type)
+ ACE_THROW_SPEC ((CORBA::SystemException));
+ //@}
+
+ 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 e7830c498cc..6f52713d2dd 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"
@@ -42,36 +45,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..6a13faa6877 100644
--- a/TAO/orbsvcs/orbsvcs/SecurityLevel2.idl
+++ b/TAO/orbsvcs/orbsvcs/SecurityLevel2.idl
@@ -271,4 +271,23 @@ module SecurityLevel2 {
#pragma prefix ""
+module TAO {
+ module SL2 {
+ local interface AccessDecision : SecurityLevel2::AccessDecision
+ {
+ /*! 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 Object obj,
+ in boolean allow_insecure_access);
+ void remove_object (in Object obj);
+
+ // Should there be some kind of "find" interface?
+ };
+ };
+};
+
#endif /* _SECURITY_LEVEL_2_IDL_ */