Bug 1421

Summary: Connection_Handler assert when using SSLIOP
Product: TAO Reporter: Wayne Erchak <werchak>
Component: ORBAssignee: DOC Center Support List (internal) <tao-support>
Status: NEW ---    
Severity: normal CC: alexander, bala, jreis, rafiq
Priority: P3    
Version: 1.3   
Hardware: SPARC   
OS: Solaris   
Attachments: run_test.pl
client_nopasswd.conf
server_nopasswd.conf

Description Wayne Erchak 2003-01-13 13:03:33 CST
I get the following assert after compiling with 5.2.8 (this is working 5.2.5 
code).  I'm using SSLIOP:

ACE_ASSERT: file C:\StentorSoft\ACE_wrappers\TAO\tao\Connection_Handler.cpp, 
line 155 assertion failed for 'this->transport_ == 0 || transport == 
0'.Aborting...

Stack dump:

TAO_Connection_Handler::transport(TAO_Transport * 0x013c4938) line 155 + 115 
bytes
TAO_IIOP_SSL_Connection_Handler::TAO_IIOP_SSL_Connection_Handler(TAO_ORB_Core * 
0x01333178, unsigned char 0x00, void * 0x013b1634) line 91
TAO_Connect_Creation_Strategy<TAO_IIOP_SSL_Connection_Handler>::make_svc_handler
(TAO_IIOP_SSL_Connection_Handler * & 0x00000000) line 36 + 58 bytes
ACE_Strategy_Connector<TAO_IIOP_SSL_Connection_Handler,ACE_SOCK_Connector,ACE_IN
ET_Addr>::make_svc_handler(TAO_IIOP_SSL_Connection_Handler * & 0x00000000) line 
1004
ACE_Connector<TAO_IIOP_SSL_Connection_Handler,ACE_SOCK_Connector,ACE_INET_Addr>:
:connect_i(TAO_IIOP_SSL_Connection_Handler * & 0x00000000, 
TAO_IIOP_SSL_Connection_Handler * * 0x00000000, const ACE_INET_Addr & {...}, 
const ACE_Synch_Options & {...}, const ACE_INET_Addr & {...}, int 0x00000000, 
int 0x00000002, int 0x00000000) line 490 + 15 bytes
ACE_Connector<TAO_IIOP_SSL_Connection_Handler,ACE_SOCK_Connector,ACE_INET_Addr>:
:connect(TAO_IIOP_SSL_Connection_Handler * & 0x00000000, const ACE_INET_Addr & 
{...}, const ACE_Synch_Options & {...}, const ACE_INET_Addr & {...}, int 
0x00000000, int 0x00000002, int 0x00000000) line 451
TAO_IIOP_SSL_Connector::make_connection(TAO_GIOP_Invocation * 0x0012dd14, 
TAO_Transport_Descriptor_Interface * 0x0012da0c, ACE_Time_Value * 0x00000000) 
line 194 + 52 bytes
TAO_Connector::connect(TAO_GIOP_Invocation * 0x0012dd14, 
TAO_Transport_Descriptor_Interface * 0x0012da0c, ACE_Time_Value * 0x00000000) 
line 264
TAO_SSLIOP_Connector::iiop_connect(TAO_SSLIOP_Endpoint * 0x013bde1c, 
TAO_GIOP_Invocation * 0x0012dd14, ACE_Time_Value * 0x00000000) line 354 + 21 
bytes
TAO_SSLIOP_Connector::connect(TAO_GIOP_Invocation * 0x0012dd14, 
TAO_Transport_Descriptor_Interface * 0x0012dc10, ACE_Time_Value * 0x00000000) 
line 261 + 23 bytes
TAO_GIOP_Invocation::perform_call(TAO_Transport_Descriptor_Interface & {...}) 
line 282 + 43 bytes
TAO_Network_Endpoint_Selector::select_endpoint(TAO_GIOP_Invocation * 
0x0012dd14) line 71 + 15 bytes
TAO_GIOP_Invocation::start() line 221
TAO_GIOP_Twoway_Invocation::start() line 876
TAO_Remote_Object_Proxy_Impl::_is_a(CORBA_Object * const 0x013b1268, const char 
* 0x00807c8c) line 56
CORBA_Object::_is_a(const char * 0x00807c8c) line 152 + 19 bytes
CosNaming::NamingContext::_narrow(CORBA_Object * 0x013b1268) line 4419 + 16 
bytes
NAMING_CLIENT::NamingClient::init(CORBA_ORB * 0x0134bb18, const 
ACE_String_Base<char> & {...}) line 33 + 33 bytes
AdvertiseCommand::connectToNamingService(NAMING_CLIENT::NamingClient & {...}) 
line 126 + 54 bytes
DLL_ORB::connectToNamingService() line 395 + 20 bytes
DLL_ORB::init(int 0x00000003, char * * 0x01319918) line 254
ACE_Service_Object_Type::init(int 0x00000009, char * * 0x01319918) line 98
ACE_Service_Config::initialize(const ACE_Service_Type * 0x0131a3f8, const char 
* 0x0131a460) line 338 + 40 bytes
ACE_Dynamic_Node::apply(int & 0x00000000) line 246 + 26 bytes
ace_yyparse(void * 0x0012f4a4) line 980 + 22 bytes
ACE_Service_Config::process_directives_i(ACE_Svc_Conf_Param * 0x0012f4a4) line 
364 + 9 bytes
ACE_Service_Config::process_directive(const char * 0x01319a20) line 463 + 9 
bytes
LaunchServices(const ACE_String_Base<char> & {...}) line 337 + 18 bytes
ace_main_i(int 0x00000001, char * * 0x01300778) line 215 + 9 bytes
main(int 0x00000001, char * * 0x01300778) line 60 + 75 bytes
Comment 1 Nanbor Wang 2003-01-14 07:02:13 CST
We may need more information. Particularly I would request you to see what the 
exact problem is -- is it that transport ==0 or transport_ == 0? Based on this 
I would request you to see why the refcount became zero in the first place. 

BTW, you are not using SSLIOP. Looks like the SSLIOP is trying to set up a IIOP 
handler for you. 
Comment 2 Wayne Erchak 2003-01-16 20:53:55 CST
Created attachment 180 [details]
run_test.pl
Comment 3 Wayne Erchak 2003-01-16 20:54:33 CST
Created attachment 181 [details]
client_nopasswd.conf
Comment 4 Wayne Erchak 2003-01-16 20:54:53 CST
Created attachment 182 [details]
server_nopasswd.conf
Comment 5 Wayne Erchak 2003-01-16 20:57:15 CST
We were able to reproduce this using an existing regression test, with some
different configuration files:
C:\StentorSoft\ACE_wrappers\TAO\orbsvcs\tests\Security\Secure_Invocation

I've attached the files that we changed:
run_test.pl
server_nopasswd.conf
client_nopasswd.conf

As you said, it looks like this is when making non-SSL calls when using SSLIOP.

Comment 6 Nanbor Wang 2003-01-17 13:26:52 CST
Some more information about the problem:

Constructing TAO_IIOP_SSL_Connection_Handler with

TAO_IIOP_SSL_Connection_Handler::
TAO_IIOP_SSL_Connection_Handler (TAO_ORB_Core *orb_core,
                                 CORBA::Boolean flag,
                                 void *arg)
  : TAO_IIOP_Connection_Handler (orb_core,
                                 flag,
                                 (ACE_static_cast (
                                    TAO_SSLIOP_Connection_Handler_State *,
                                    arg))->tcp_properties,0)
{

Initializes a TAO_IIOP_Connection_Handler

The constructor for TAO_IIOP_Connection_Handler calls:

	  this->transport (specific_transport);
	  TAO_Transport::release (specific_transport);
which sets the transport to an TAO_IIOP_Transport.

At this point the assert in TAO_Connection_Handler is satisfied
  // The transport can be reset, but not changed!
  ACE_ASSERT(this->transport_ == 0 || transport == 0);

Now the derived class (TAO_IIOP_SSL_Connection_Handler) creates an 
TAO_IIOP_SSL_Transport and calls

  // store this pointer (indirectly increment ref count)
  this->transport (specific_transport);
  TAO_Transport::release (specific_transport);

Of course since the base class already created a transport, the assert will 
fail. So the fact that TAO_IIOP_SSL_Connection_Handler inherits from 
TAO_IIOP_Connection_Handler is against the assert.

Question: Why does TAO_IIOP_Connection_Handler create a transport only to have 
it replaced by the derived class?
Comment 7 Nanbor Wang 2003-01-17 14:43:31 CST
Jon, thanks very much for the explanation. I think I know what is going on. 

I will assign the bug to myself
Comment 8 Nanbor Wang 2003-01-17 14:43:47 CST
Accepting the bug
Comment 9 Nanbor Wang 2003-01-20 06:31:18 CST
*** Bug 1424 has been marked as a duplicate of this bug. ***
Comment 10 Nanbor Wang 2003-01-30 17:28:25 CST
Fixed! The relevant ChangeLog entry is

Thu Jan 30 17:30:04 2003  Balachandran Natarajan
<bala@isis-server.isis.vanderbilt.edu>
Comment 11 rafiq 2003-03-16 22:52:51 CST
I modified a few lines of code for the Security Service i.e Secure Invocation 
example in order to use naming Service which the transport is SSL.

I tried a few setups like NamingService/server in windows and as well 
NamingService/Server in solaris. But the problem is same.

Here is the client code.

// -*- C++ -*-

#include "ace/Get_Opt.h"

#include "FooC.h"
#include "orbsvcs/SecurityC.h"
#include "orbsvcs/CosNamingC.h"
#include <ace/OS.h>


ACE_RCSID (Secure_Invocation,
           client,
           "client.cpp,v 1.7 2002/01/29 20:20:56 okellogg Exp")

const char *ior = "file://test.ior";

void
insecure_invocation_test (CORBA::ORB_ptr orb,
                          CORBA::Object_ptr obj
                          ACE_ENV_ARG_DECL)
{
  // 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 =
    orb->create_policy (Security::SecQOPPolicy,
                        no_protection
                        ACE_ENV_ARG_PARAMETER);
  ACE_CHECK;

  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 =
    obj->_set_policy_overrides (policy_list,
                                CORBA::SET_OVERRIDE
                                ACE_ENV_ARG_PARAMETER);
  ACE_CHECK;

  Foo::Bar_var server =
    Foo::Bar::_narrow (object.in () ACE_ENV_ARG_PARAMETER);
  ACE_CHECK;

  if (CORBA::is_nil (server.in ()))
    {
      ACE_ERROR ((LM_ERROR,
                  "(%P|%t) ERROR: Object reference <%s> is "
                  "nil.\n",
                  ior));

      ACE_THROW (CORBA::INTERNAL ());
    }

  ACE_TRY
    {
      // This invocation should result in a CORBA::NO_PERMISSION
      // exception.
      server->baz (ACE_ENV_SINGLE_ARG_PARAMETER);
      ACE_TRY_CHECK;
    }
  ACE_CATCH (CORBA::NO_PERMISSION, exc)
    {
      ACE_DEBUG ((LM_INFO,
                  "(%P|%t) Received CORBA::NO_PERMISSION from "
                  "server, as expected.\n"));

      return;
    }
  ACE_ENDTRY;
  ACE_CHECK;

  ACE_ERROR ((LM_ERROR,
              "(%P|%t) ERROR: CORBA::NO_PERMISSION was not thrown.\n"
              "(%P|%t) ERROR: It should have been thrown.\n"));

  ACE_THROW (CORBA::INTERNAL ());
}

void
secure_invocation_test (CORBA::Object_ptr object
                        ACE_ENV_ARG_DECL)
{
  Foo::Bar_var server =
    Foo::Bar::_narrow (object ACE_ENV_ARG_PARAMETER);
  ACE_CHECK;

  if (CORBA::is_nil (server.in ()))
    {
      ACE_ERROR ((LM_ERROR,
                  "(%P|%t) ERROR: Object reference <%s> is "
                  "nil.\n",
                  ior));

      ACE_THROW (CORBA::INTERNAL ());
    }

  ACE_DEBUG ((LM_DEBUG,
              "\n"
              "Secure_Invocation Called...\n"));
  // This invocation should return successfully.
  server->baz (ACE_ENV_SINGLE_ARG_PARAMETER);
  ACE_CHECK;

  server->shutdown (ACE_ENV_SINGLE_ARG_PARAMETER);
  ACE_CHECK;
}

int
parse_args (int argc, char *argv[])
{
  ACE_Get_Opt get_opts (argc, argv, "k:");
  int c;

  while ((c = get_opts ()) != -1)
    switch (c)
      {
      case 'k':
        ior = get_opts.opt_arg ();
        break;
      case '?':
      default:
        ACE_ERROR_RETURN ((LM_ERROR,
                           "Usage:  %s "
                           "-k <ior> "
                           "\n",
                           argv [0]),
                          -1);
      }
  // Indicates sucessful parsing of the command line
  return 0;
}

int
main (int argc, char *argv[])
{
  ACE_TRY_NEW_ENV
    {
      CORBA::ORB_var orb =
        CORBA::ORB_init (argc, argv, "" ACE_ENV_ARG_PARAMETER);
 //     ACE_TRY_CHECK;

      if (parse_args (argc, argv) != 0)
        return 1;

      //CORBA::Object_var object = orb->string_to_object (ior 
ACE_ENV_ARG_PARAMETER);
      ACE_TRY_CHECK;

      // This test sets creates a Security::QOPPolicy with the
      // Quality-of-Protection set to "no protection."  It then
      // invokes a method on the server (insecurely), which should
      // then result in a CORBA::NO_PERMISSION exception.
      //
      // The server is not shutdown by this test.

//      insecure_invocation_test (orb.in (), object.in () 
ACE_ENV_ARG_PARAMETER);
      //secure_invocation_test (object.in () ACE_ENV_ARG_PARAMETER);

	  //    ACE_TRY_CHECK;


		// rafiq code begin
  ACE_TRY
    {
      CosNaming::Name name (1);

      name.length (1);
      name[0].id = CORBA::string_dup ("FOO");

	  //
	  // Policy Security
  Security::QOP qop = Security::SecQOPNoProtection;

  CORBA::Any no_protection;
  no_protection <<= qop;

  // Create the Security::QOPPolicy.
  CORBA::Policy_var policy =
    orb->create_policy (Security::SecQOPPolicy,
                        no_protection
                        ACE_ENV_ARG_PARAMETER);
  ACE_CHECK;

  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).

  ACE_CHECK;


      CORBA::Object_var naming_context_object = orb->resolve_initial_references 
("NameService" ACE_ENV_ARG_PARAMETER);
      ACE_TRY_CHECK;

      if (CORBA::is_nil (naming_context_object.in ()))
        ACE_ERROR_RETURN ((LM_ERROR,
                           "Cannot resolve Naming Service\n"),
                          1);

	 // CosNaming::NamingContextExt_var naming_context_;
      //naming_context_ = CosNaming::NamingContextExt::_narrow 
(naming_context_object.in () ACE_ENV_ARG_PARAMETER);




  CORBA::Object_var unprotected_obj =
    naming_context_object->_set_policy_overrides (policy_list,
                                CORBA::SET_OVERRIDE
                                ACE_ENV_ARG_PARAMETER);
  CosNaming::NamingContextExt_var naming_context_ = 
CosNaming::NamingContextExt::_narrow (unprotected_obj.in ());
  //CosNaming::NamingContextExt_var naming_context_ = 
CosNaming::NamingContextExt::_narrow (naming_context_object.in ());

  CORBA::String_var str_name = naming_context_->to_string (name 
ACE_ENV_ARG_PARAMETER);







      ACE_TRY_CHECK;

      CORBA::Object_var factory_object;

      ACE_TRY_EX (InnerBlock)
        {
          // Resolve the name using the stringified form of the name
          factory_object =
            naming_context_->resolve_str (str_name.in ()
                                                ACE_ENV_ARG_PARAMETER);
          ACE_TRY_CHECK_EX (InnerBlock);
        }
      ACE_CATCH (CosNaming::NamingContext::NotFound, ex)
        {
        }
      ACE_ENDTRY;

  //CORBA::Object_var unprotected_factory_object = factory_object-
>_set_policy_overrides (policy_list, CORBA::SET_OVERRIDE);

      // Narrow
      //corbaname::Status_var factory = corbaname::Status::_narrow 
(factory_object.in () ACE_ENV_ARG_PARAMETER);
	  //Foo::Bar_var factory = Foo::Bar::_narrow 
(unprotected_factory_object.in () ACE_ENV_ARG_PARAMETER);
	  Foo::Bar_var factory = Foo::Bar::_narrow (factory_object.in () 
ACE_ENV_ARG_PARAMETER);
	  //Foo::Bar_var factory = Foo::Bar::_narrow (object.in () 
ACE_ENV_ARG_PARAMETER);
      ACE_TRY_CHECK;

      if (CORBA::is_nil (factory.in ()))
        {
          ACE_ERROR_RETURN ((LM_ERROR,
                             "Object reference <%s> is nil\n",
                             ""),
                            1);
        }
ACE_TRY_CHECK;
      // Invoke a request on the server
      //CORBA::Boolean ret_value = factory->print_status 
(ACE_ENV_SINGLE_ARG_PARAMETER);
	  factory->baz (ACE_ENV_SINGLE_ARG_PARAMETER);
      ACE_TRY_CHECK;

    }
  ACE_CATCH (CosNaming::NamingContext::NotFound, ex)
    {
      ACE_PRINT_EXCEPTION (ex, "CosNaming::NamingContext::NotFound");
    }
  ACE_CATCH (CORBA::SystemException, ex)
    {
      ACE_PRINT_EXCEPTION (ex, "A system exception on client side");
      return -1;
    }
  ACE_CATCHANY
    {
      ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "client");
      return -1;
    }
  ACE_ENDTRY;
		 //rafiq code end */



      // This test uses the default secure SSLIOP settings to securely
      // invoke a method on the server.  No exception should occur.
      //
      // The server *is* shutdown by this test.
      //secure_invocation_test (object.in () ACE_ENV_ARG_PARAMETER);

  ACE_DEBUG ((LM_DEBUG,
              "\n"
              "Secure_Invocation Destroying...\n"));
      ACE_TRY_CHECK;

      orb->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
      ACE_TRY_CHECK;
    }
  ACE_CATCHANY
    {
      ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,
                           "Caught exception:");
      return 1;
    }
  ACE_ENDTRY;

  ACE_DEBUG ((LM_DEBUG,
              "\n"
              "Secure_Invocation test passed.\n"));

  return 0;
}


Here is the runtime output

bash-2.03$ ./client -ORBInitRef NameService=iioploc://192.168.7.208:18888/NameS
ervice -ORBSvcConf client.conf -ORBDebug -ORBDebugLevel 99
starting up daemon ./client
ACE_DLL_Handle::open: calling dlopen on "TAO_SSLIOP"
opening dynamic service SSLIOP_Factory
ACE_SSL (4220|1) error code: 33558530 - error:02001002:system library:fopen:No s
uch file or directory
(4220|1) SSLIOP_Factory: No DH parameters found in certificate <clientcert.pem>;
 either none are needed (RSA) or problems will ensue later.
(4220|1) SSLIOP loaded SSL certificate from clientcert.pem
(4220|1) SSLIOP loaded Private Key from clientkey.pem
did dynamic on SSLIOP_Factory, error = 0
opening static service Resource_Factory
did static on Resource_Factory, error = 0
TAO (4220|1) Loaded protocol <SSLIOP_Factory>
TAO (4220|1) created new ORB <>
TAO (4220|1) - TAO_Connector::make_mprofile <iioploc://192.168.7.208:18888/NameS
ervice>
TAO (4220|1) Connector::connect - looking for SSLIOP connection.
TAO (4220|1) - Transport_Cache_Manager::find_i, unable to locate a free connecti
on
TAO (4220|1) - Transport_Cache_Manager::fill_set_i, current_size = 0, cache_maxi
mum = 128
TAO (4220|1) Connector::connect - looking for IIOP connection.
(4220|1) IIOP_SSL_Connector::connect making a new connection
ACE_ASSERT: file Connection_Handler.cpp, line 155 assertion failed for 'this->tr
ansport_ == 0 || transport == 0'.Aborting...
Abort (core dumped)
bash-2.03$






































































                                                                               
Comment 12 Johnny Willemsen 2007-09-20 03:08:59 CDT
to pool