summaryrefslogtreecommitdiff
path: root/TAO/orbsvcs/orbsvcs/SSLIOP
diff options
context:
space:
mode:
Diffstat (limited to 'TAO/orbsvcs/orbsvcs/SSLIOP')
-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
3 files changed, 289 insertions, 50 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 ());