Using CORBA Request-Level Interceptors

     Previous  Next    Open TOC in new window  Open Index in new window  View as PDF - New Window  Get Adobe Reader - New Window
Content starts here

InterceptorSec Sample Interceptors

This topic includes the following sections:

Before trying out the steps described in this chapter, make sure you have completed all the steps described in PersonQuery Sample Application.

 


How the PersonQuery Sample Interceptors Work

The InterceptorSec sample interceptors show a simple client/server interceptor pair that implement a basic security model. The InterceptorSec client-side interceptor simply logs each client request that is handled by the ORB. The InterceptorSec target-side interceptor implements a simple security mechanism that checks to see whether the user of the client application is authorized to perform the operation in the request.

The InterceptorSec sample interceptors show the client and target interceptor pair initialized through a single initialization function and implemented in a single library. Since a single initialization function is called, the interceptor registration command registers one initialization function and one implementation library.

How the InterceptorSec Target-side Interceptor Works

When the target-side ORB receives a request, the ORB calls the InterceptorSec target-side interceptor and passes the RequestContext and DataInputStream objects from the client request.

The target-side interceptor then does the following to authorize the user of the client application for the operation contained in the request:

  1. Checks to see if the request is an invocation on the PersonQuery interface. If it is not, the interceptor returns a INVOKE_NO_EXCEPTION.
  2. If the operation contained in the request is an invocation on the PersonQuery interface, the interceptor:
    1. Obtains a reference to the SecurityCurrent object, which the interceptor then narrows.
    2. Invokes the SecurityContext object, requesting the attribute list for the user of the client application.
    3. Walks through the attribute list to obtain two attributes:
    4. PrimaryGroupId
      Identifies the client name of the user of the client application. In this interceptor, the client name must contain either the character r or a NULL string.
      AccessId
      Identifies the user of the client application. In this interceptor, the username must have the characters R, P, or N (either upper- or lowercase).

    5. Matches the user against the PrimaryGroupId and the AccessId. If the user successfully matches the criteria for these two attributes, the interceptor returns INVOKE_NO_EXCEPTION.
    6. If no match is found, the interceptor returns REPLY_EXCEPTION, which prevents the request from being sent to the target object. Instead, the ORB returns an exception to the client application.

The sections that immediately follow discuss interceptor security topics and show code fragments of interest from the InterceptorSec target-side interceptor.

Using the SecurityCurrent Object

Interceptors obtain the SecurityCurrent object from the ORB, not from the Bootstrap object. The SecurityCurrent object available from the ORB has the API that interceptors need for obtaining information about the client.

To obtain the SecurityCurrent object, your interceptors can invoke the resolve_initial_references("SecurityCurrent") operation on the ORB. The interceptor can then narrow the SecurityCurrent reference to a SecurityCurrentLevel1 current.

Obtaining the SecurityCurrent Object

The SecurityCurrent object is available only through the ORB, and this object's primary functionality is to provide CORBA server applications access to attributes related to the client invocation.

The ORB's resolve_initial_references("SecurityCurrent") method provides the interceptor a reference to a SecurityCurrent object from which the interceptor is provided with Level 1 Security functionality. The interceptor can obtain the attributes of the client invocation via the get_attributes method on the SecurityCurrent object, which returns an attribute list to the interceptor. The attribute list contains the attributes that pertain to the user of the client application that performed the invocation being intercepted. The behavior of any and all methods from the CORBA security service is still the same, with the exceptions noted above.

The following C++ code fragment shows obtaining the SecurityCurrent object.

try
{
sec_current = m_orb->resolve_initial_references("SecurityCurrent");
}
catch (...)
{
*m_outfile <<
"ERROR: ORB::resolve_initial_references threw exception"
<< endl << endl << flush;
excep_val = new CORBA::UNKNOWN();
return Interceptors::REPLY_EXCEPTION;
}
if (CORBA::is_nil(sec_current.in()))
{
*m_outfile << "ERROR: No SecurityCurrent present"
<< endl << endl << flush;
excep_val = new CORBA::NO_PERMISSION();
return Interceptors::REPLY_EXCEPTION;
}

m_security_current = SecurityLevel1::Current::_narrow(sec_current.in());
if (!m_security_current)
{
*m_outfile << "ERROR: Couldn't narrow security
current to SecurityLevel1::Current"
<< endl << endl << flush;
excep_val = new CORBA::NO_PERMISSION();
return Interceptors::REPLY_EXCEPTION;
}

Creating the List of User Attributes

The code fragments in this section show how the InterceptorSec target-side interceptor creates a list of user attributes and then walks through this list to determine if the user matches the authorization criteria.

In the InterceptorSec sample, creating the list of attributes, then walking through them are done in separate steps. Note that if you specify a client attribute list length of zero (0) to be returned, the SecurityCurrent object returns all the attributes for the client.

// Get the attributes that correspond to the information that we need to
// do an authorization check:
// PrimaryGroupId (clientname of the logged in client)
// AccessId (username of the logged in client)
Security::AttributeList_var client_attr = 0;
try
{
client_attr = m_security_current->get_attributes(*m_attributes_to_get);

The following fragment shows creating the list:

   Security::AttributeTypeList_var attr = new Security::AttributeTypeList(2);
if (!attr.ptr())
{
cout <<
"ERROR: can't allocation security list: Out of memory"
<< endl << endl << flush;
return;
}
attr.inout().length(2);
attr[(CORBA::ULong)0].attribute_family.family_definer = 0;
attr[(CORBA::ULong)0].attribute_family.family = 1;
attr[(CORBA::ULong)0].attribute_type = Security::PrimaryGroupId;
attr[(CORBA::ULong)1].attribute_family.family_definer = 0;
attr[(CORBA::ULong)1].attribute_family.family = 1;
attr[(CORBA::ULong)1].attribute_type = Security::AccessId;
m_attributes_to_get = attr._retn();
return;

The following fragment shows walking through the attribute list to check whether the user matches the authorization criteria:

if  (client_attr[i].attribute_type.attribute_type == Security::PrimaryGroupId)
{
//
// This attribute is the client name.
// Compare to some client name value.
// For this example, we're going to accept anything with
// an 'r' in it, or a NULL string. You will want to compare
// the client name to some set of values you have authorized.
//
if ((strlen(value_buffer) == 0) ||
(strchr(value_buffer, 'r') != 0))
{
*m_outfile << " INFO: Valid client name found: "
<< value_buffer << endl;
clientname_ok = 1;
}
else
{
*m_outfile << " ERROR: Invalid client name found: "
<< value_buffer << endl;
}
}
else if (client_attr[i].attribute_type.attribute_type == Security::AccessId)
{
// This attribute is the user name. We're arbitrarily
// choosing to authorize anyone who has an 'r', 'n', or 'p'
// in their user id. You will likely want to choose
// some other criteria for authorization.
//
if ((strchr(value_buffer, 'r') != 0) ||
(strchr(value_buffer, 'R') != 0) ||
(strchr(value_buffer, 'P') != 0) ||
(strchr(value_buffer, 'p') != 0) ||
(strchr(value_buffer, 'N') != 0) ||
(strchr(value_buffer, 'n') != 0))
{
*m_outfile << " INFO: Valid username found: "
<< value_buffer << endl;
username_ok = 1;
}

 


Registering and Running the PersonQuery Interceptors

When you run the makefile that builds the PersonQuery sample application in PersonQuery Sample Application, the entire set of sample interceptors are built as well, including the InterceptorSec interceptor. This section describes how to register the InterceptorSec interceptor so that it works with PersonQuery application at run time.

To register and run the InterceptorSec client and server interceptors:

  1. Change directory to the InterceptorSec sample directory, where workdirectory represents the name of the directory into which you copied the interceptor sample applications in Chapter , "PersonQuery Sample Application:"
  2. Windows 2003

    > cd <workdirectory>\cxx\security_cxx

    UNIX

    $ cd <workdirectory>/cxx/security_cxx
  3. Register the interceptor:
  4. Windows 2003

    > nmake -f makefile.nt config

    UNIX

    $ make -f makefile.mk config
  5. Boot the CORBA server and run the CORBA client:
  6. Windows 2003

    > cd <workdirectory>\cxx\app_cxx
    > tmboot -y
    > PersonQueryClient

    UNIX

    > cd <workdirectory>/cxx/app_cxx
    > tmboot -y
    > PersonQueryClient
  7. Perform any number of invocations using the PersonQuery client application, using the command syntax described in PersonQuery Sample Application.
  8. Stop the PersonQuery application:
  9. > tmshutdown -y

 


Examining the Interceptor Output

The InterceptorSec client and target interceptors log their output to the files named, respectively, InterceptorSecClientxxx.out and InterceptorSecTargetxxx.out. These files contain debugging output from the interceptors that is automatically loaded and executed by the ORB for the PersonQuery application.

 


Unregistering the Interceptors

After you have run the PersonQuery sample application with the InterceptorSec sample interceptors, you can unregister those interceptors using the following steps:

  1. Shut down all running CORBA applications by entering the following command:
  2. > tmshutdown -y
  3. Change directory to the InterceptorSec sample directory, where workdirectory represents the name of the directory into which you copied the interceptor sample applications in Chapter , "PersonQuery Sample Application:"
  4. Windows 2003

    > cd <workdirectory>\cxx\security_cxx

    UNIX

    $ cd <workdirectory>/cxx/security_cxx
  5. Unregister the interceptors:
  6. Windows 2003

    > nmake -f makefile.nt unconfig

    UNIX

    $ make -f makefile.mk unconfig

  Back to Top       Previous  Next