summaryrefslogtreecommitdiff
path: root/TAO/orbsvcs/orbsvcs
diff options
context:
space:
mode:
authorPhil Mesnier <mesnier_p@ociweb.com>2007-07-12 17:10:11 +0000
committerPhil Mesnier <mesnier_p@ociweb.com>2007-07-12 17:10:11 +0000
commit6162ee8bee93cff083ff63c024fecc172e4f01fb (patch)
treec5212f5864609dc97de2e5e96a92c645d3a46346 /TAO/orbsvcs/orbsvcs
parentdeac37b9ee25368f0337d10682ea2c574962bb4a (diff)
downloadATCD-6162ee8bee93cff083ff63c024fecc172e4f01fb.tar.gz
Thu Jul 12 16:51:30 UTC 2007 Phil Mesnier <mesnier_p@ociweb.com>
Diffstat (limited to 'TAO/orbsvcs/orbsvcs')
-rw-r--r--TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_Connector.cpp2
-rw-r--r--TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_Invocation_Interceptor.cpp205
-rw-r--r--TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_Invocation_Interceptor.h22
-rw-r--r--TAO/orbsvcs/orbsvcs/SSLIOP/SSLIOP_ORBInitializer.cpp31
-rw-r--r--TAO/orbsvcs/orbsvcs/Security/SL2_SecurityManager.cpp325
-rw-r--r--TAO/orbsvcs/orbsvcs/Security/SL2_SecurityManager.h226
-rw-r--r--TAO/orbsvcs/orbsvcs/Security/Security_ORBInitializer.cpp74
-rw-r--r--TAO/orbsvcs/orbsvcs/SecurityLevel2.idl35
8 files changed, 781 insertions, 139 deletions
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_ */