|
|
This topic contains the following sections:
The Bootstrap object in the WLE product has been enhanced so that users can specify that all communication to a given IIOP Listener/Handler be protected. The Bootstrap object supports corbaloc
and corbalocs
Uniform Resource Locator (URL) address formats to be used when specifying the location of the IIOP Listener/Handler. The type of security provided depends on the format of URL used to specify the location of the IIOP Listener/Handler.
As with the Host and Port address format, you use the URL address formats to specify the location of the IIOP Listener/Handler, but the bootstrapping process behaves differently. When using the corbaloc
or corbalocs
URL address format, the initial connection to the IIOP Listener/Handler is deferred until either:
Understanding the Address Formats of the Bootstrap Object
Using the corbalocs
URL address format indicates that the SSL protocol is used to the protect at least the integrity of the connection between the principal and the IIOP Listener/Handler.
Table 5-1
Both the corbaloc
and corbalocs
URL address formats provide stringified object references that are easily manipulated in both TCP/IP and Domain Name System (DNS) environments. The corbaloc
and corbalocs
URL address formats contain a DNS-style host name or an IP address and port.
The URL address formats follow and extend the definition of object URLs adopted by the Object Management Group (OMG) as part of the Interoperable Naming Service submission. The WLE software also extends the URL format described in the OMG Interoperable Naming Service submission to support a secure form that is modeled after the URL for secure HTTP, as well as to support functionality in previous releases of the WLE product.
Listing 5-1 contains examples of the new URL address formats.
Listing 5-1
Examples of the corbaloc
and corbalocs
URL Address Formats
corbaloc://555xyz.com:1024,corbaloc://555backup.com:1022, As an enhancement to the URL syntax described in the OMG Interoperable Naming Service submission, the WLE product extends the syntax to support a list of multiple URLs, each with a different scheme. Listing 5-2 contains examples of specifying multiple URLs.
Listing 5-2
Examples of Specifying Multiple URL Address Formats
corbalocs://555xyz.com:1024,corbaloc://555xyz.com:1111 In the examples in Listing 5-2, if the parser reaches the URL corbaloc://force.com:1111
, it resets its internal state as if it had never attempted secure connections, and then begins attempting unprotected connections. This situation occurs if the client application has not set any SSL parameters on the Credentials object.
The following sections describe the behavior when using the different address formats of the Bootstrap object.
If a WLE client application uses the Host and Port address format of the Bootstrap object, the constructor method of the Bootstrap object constructs an object reference using the specified host name and port number. The invocation to the IIOP Listener/Handler is made without the protections offered by the SSL protocol.
The client application can still authenticate using Username/Password authentication. However, since the bootstrapping process is performed over an unprotected and unverified link, all communications are vulnerable to the following security attacks:
corbaloc://555last.com:1999
corbalocs://555xyz.com:1024,(corbalocs://555backup.com:1022|corbalocs://555last.com:1999)
corbaloc://555xyz.com:1111
corbalocs://24.128.122.32:1011, corbalocs://24.128.122.34
corbalocs://ctxobj.com:3434,corbalocs://mthd.com:3434,corbaloc://force.com:1111 Using the Host and Port Address Format
Note: If the IIOP Listener/Handler is configured for the SSL protocol and the Host and Port address format of the Bootstrap object is used, the invocation on the specified WLE object results in a INVALID_DOMAIN exception.
By default, the invocation on the IIOP Listener/Handler is unprotected when using the corbaloc
URL address format and Username/Password authentication. Therefore, all communications are vulnerable to the following security attacks:
Using the corbaloc URL Address Format
You can protect the bootstrapping process when using the corbaloc
URL address format by using the SecurityLevel2::Current::authenticate()
method, specifying that certificate-based authentication is to be used, and setting the invocation_methods_required
method on the Credentials object.
Note:
If the IIOP Listener/Handler is configured for the SSL protocol and not for certificate-based authentication and the corbaloc
URL address format is used, the invocation on the specified WLE object results in an INVALID_DOMAIN
exception.
BEA recommends that existing WLE applications migrate to the corbaloc
URL address format instead of using the Host and Port Address format.
The corbalocs
URL address format is the recommended format to use to ensure that communications between principals and the IIOP Listener/Handler are protected. The corbalocs
URL address format functions in the same way as the corbaloc
URL address format, except the SSL protocol is used to protect all communications with the IIOP Listener/Handler, the CORBA C++ ORB, or the CORBA Java ORB regardless of the type of authentication used.
When the defaults are used with the corbalocs
URL address format, communications are vulnerable only to Denial of Service security attacks. Using the SSL protocol and certificate-based authentication guards against Sniffer, Tamper, and Replay attacks. In addition, the validation check of the host specified in the digital certificate guards against Man-in-the-Middle attacks.
To use the corbalocs
URL address format, the IIOP Listener/Handler, the CORBA C++ ORB, or the CORBA Java ORB must be configured to enable the use of the SSL protocol. For more information about configuring the IIOP Listener/Handler, the CORBA C++ ORB, or the CORBA Java ORB for the SSL protocol, see Configuring the WLE Environment for the SSL Protocol.
This section describes implementing Username/Password authentication in WLE applications.
The Security sample application demonstrates Username/Password authentication. The Security sample application requires each student using the application to have an ID and a password. The Security sample application works in the following manner:
Using the corbalocs URL Address Format
Using Username/Password Authentication
The Security Sample Application
Figure 5-1 illustrates the Security sample application.
The source files for the Security sample application are located in the \samples\corba\university directory in the WLE software. For information about building and running the Security sample application, see Building and Running the CORBA Sample Applications.
When using Username/Password authentication, write client application code that does the following:
The SecurityLevel2::PrincipalAuthenticator interface is defined in the CORBAservices Security Service specification. This interface contains two methods that are use to accomplish the authentication of the principal. There are two methods because authentication of principals may require more than one step. The authenticate() method allows the caller to authenticate and optionally select attributes for the principal of this session.
The WLE product extends the PrincipalAuthenticator object with functionality to support similar security to that found in BEA TUXEDO. The enhanced functionality is provided by the Tobj::PrincipalAuthenticator interface.
The methods defined for the Tobj::PrincipalAuthenticator interface provide a focused, simplified form of the equivalent CORBA-defined interface. You can use either the CORBA-defined or the WLE extensions when developing a WLE application.
The Tobj::PrincipalAuthenticator interface provides the same functionality as the SecurityLevel2::PrincipalAuthenticator interface. However, unlike the SecurityLevel2::PrincipalAuthenticator::authenticate() method, the logon() method of the Tobj::PrincipalAuthenticator interface does not return a Credentials object. As a result, WLE applications that need to use more than one principal identity are required to call the Current::get_credentials() method immediately after the logon() method to retrieve the Credentials object as a result of the logon. Retrieval of the Credentials object directly after a logon method should be protected with serialized access.
The following sections contain C++ and Java code examples that illustrate implementing Username/Password authentication. For a Visual Basic code example, see Automation Security Reference.
Listing 5-3 contains C++ code that performs Username/Password authentication using the SecurityLevel2::PrincipalAuthenticator::authenticate() method.
Listing 5-3 C++ Client Application that uses the SecurityLevel2::PrincipalAuthenticator::authenticate() Method
...
//Create Bootstrap object
Tobj_Bootstrap* bootstrap = new Tobj_Bootstrap(orb,
corbalocs://sling.com:2143);
//Get SecurityCurrent object
CORBA::Object_var var_security_current_oref =
bootstrap.resolve_initial_references("SecurityCurrent");
SecurityLevel2::Current_var var_security_current_ref =
SecurityLevel2::Current::_narrow(var_security_current_oref.in());
//Get the PrincipalAuthenticator
SecurityLevel2::PrincipalAuthenticator_var var_principal_authenticator_oref =
var_security_current_oref->principal_authenticator();
const char * user_name = "john"
const char * client_name = "university";
char system_password[31] = {`\0'};
char user_password[31] = {`\0'};
//Determine the security level
Tobj::AuthType auth_type = var_bea_principal_authenticator->get_auth_type();
switch (auth_type)
{
case Tobj::TOBJ_NOAUTH;
break;
case Tobj::TOBJ_SYSAUTH
strcpy(system_password, "sys_pw");
case Tobj::TOBJ_APPAUTH
strcpy(system_password, "sys_pw");
strcpy(user_password, "john_pw");
break;
}
if (auth_type != Tobj::TOBJ_NOAUTH)
{
SecurityLevel2::Credentials_var creds;
Security::Opaque_var auth_data;
Security::AttributeList_var privileges;
Security::Opaque_var cont_data;
Security::Opaque_var auth_spec_data;
var_bea_principalauthenticator->build_auth_data(user_name,
client_name,
system_password,
user_password,
NULL,
auth_data,
privileges);
Security::AuthenticationStatus status =
var_bea_principalauthenticator->authenticate(
Tobj::TuxedoSecurity,
user_name,
auth_data,
privileges,
creds,
cont_data, auth_spec_data);
if (status != Security::SecAuthSuccess)
{
//Failed authentication
return;
}
}
// Proceed with application
...
Listing 5-4 contains Java code that performs Username/Password authentication using the SecurityLevel2.PrincipalAuthenticator.authenticate() method.
Listing 5-4 Java Client Application that uses the SecurityLevel2.PrincipalAuthenticator.authenticate() Method
...
// Create Bootstrap object
Tobj_Bootstrap bs =
new Tobj_Bootstrap(orb, corbalocs://sling.com:2143);
// Get SecurityCurrent object
org.omg.CORBA.Object secCurObj =
bs.resolve_initial_references( "SecurityCurrent" );
org.omg.SecurityLevel2.Current secCur2Obj =
org.omg.SecurityLevel2.CurrentHelper.narrow(secCurObj);
// Get Principal Authenticator
org.omg.Security.PrincipalAuthenticator princAuth =
secCur2Obj.principal_authenticator();
com.beasys.Tobj.PrincipalAuthenticator auth =
Tobj.PrincipalAuthenticatorHelper.narrow(princAuth);
// Get Authentication type
com.beasys.Tobj.AuthType authType = auth.get_auth_type();
// Initialize arguments
String userName = "John";
String clientName = "Teller";
String systemPassword = null;
String userPassword = null;
byte[] userData = new byte[0];
// Prepare arguments according to security level requested
switch(authType.value())
{
case com.beasys.Tobj.AuthType._TPNOAUTH:
break;
case com.beasys.Tobj.AuthType._TPSYSAUTH:
systemPassword = "sys_pw";
break;
case com.beasys.Tobj.AuthType._TPAPPAUTH:
systemPassword = "sys_pw";
userPassword = "john_pw";
break;
}
// Build security data
org.omg.Security.OpaqueHolder auth_data =
new org.omg.Security.OpaqueHolder();
org.omg.Security.AttributeListHolder privs =
new Security.AttributeListHolder();
auth.build_auth_data(userNname, clientName, systemPassword,
userPassword, userData, authData,
privs);
// Authenticate user
org.omg.SecurityLevel2.CredentialsHolder creds =
new org.omg.SecurityLevel2.CredentialHolder();
org.omg.Security.OpaqueHolder cont_data =
new org.omg.Security.OpaqueHolder();
org.omg.Security.OpaqueHolder auth_spec_data =
new org.omg.Security.OpaqueHolder();
org.omg.Security.AuthenticationStatus status =
auth.authenticate(com.beasys.Tobj.TuxedoSecurity.value,
0, userName, auth_data.value(),
privs.value(), creds, cont_data,
auth_spec_data);
if (status != AuthenticatoinStatus.SecAuthSuccess)
System.exit(1);
}
...
Listing 5-5 contains C++ code that performs Username/Password authentication using the Tobj::PrincipalAuthenticator::logon() method.
Listing 5-5 C++ Client Application that uses the Tobj::PrincipalAuthenticator::logon() Method
...
CORBA::Object_var var_security_current_oref =
bootstrap.resolve_initial_references("SecurityCurrent");
SecurityLevel2::Current_var var_security_current_ref =
SecurityLevel2::Current::_narrow(var_security_current_oref.in());
//Get the PrincipalAuthenticator
SecurityLevel2::PrincipalAuthenticator_var var_principal_authenticator_oref =
var_security_current_oref->principal_authenticator();
//Narrow the PrincipalAuthenticator
Tobj::PrincipalAuthenticator_var var_bea_principal_authenticator =
Tobj::PrincipalAuthenticator::_narrow
var_principal_authenticator_oref.in());
const char * user_name = "john"
const char * client_name = "university";
char system_password[31] = {`\0'};
char user_password[31] = {`\0'};
//Determine the security level
Tobj::AuthType auth_type = var_bea_principal_authenticator->get_auth_type();
switch (auth_type)
{
case Tobj::TOBJ_NOAUTH;
break;
case Tobj::TOBJ_SYSAUTH
strcpy(system_password, "sys_pw");
case Tobj::TOBJ_APPAUTH
strcpy(system_password, "sys_pw");
strcpy(user_password, "john_pw");
break;
}
if (auth_type != Tobj::TOBJ_NOAUTH)
{
SecurityLevel2::Credentials_var creds;
Security::Opaque_var auth_data;
Security::AttributeList_var privileges;
Security::Opaque_var cont_data;
Security::Opaque_var auth_spec_data;
var_bea_principalauthenticator->build_auth_data(user_name,
client_name,
system_password,
user_password,
NULL,
auth_data,
privileges);
//Determine the security level
Tobj::AuthType auth_type = var_bea_principal_authenticator->get_auth_type();
Security::AuthenticationStatus status = var_bea_principal_authenticator->logon(
user_name,
client_name,
system_password,
user_password,
0);
if (status != Security::SecAuthSuccess)
{
//Failed authentication
return;
}
}
// Proceed with application
...
// Log off
try
{
logoff();
}
...
Listing 5-6 contains Java code that performs Username/Password authentication using the Tobj.PrincipalAuthenticator.logon() method.
Listing 5-6 Java Client Application That Uses the Tobj.PrincipalAuthenticator.logon() Method
...
// Create bootstrap object
Tobj_Bootstrap bs =
new Tobj_Bootstrap(orb, corbaloc://sling.com;2143);
// Get security current
org.omg.CORBA.Object secCurObj =
bs.resolve_initial_references( "SecurityCurrent" );
org.omg.SecurityLevel2.Current secCur2Obj =
org.omg.SecurityLevel2.CurrentHelper.narrow(secCurObj);
// Get Principal Authenticator
org.omg.Security.PrincipalAuthenticator princAuth =
secCur2Obj.principal_authenticator();
com.beasys.Tobj.PrincipalAuthenticator auth =
Tobj.PrincipalAuthenticatorHelper.narrow(princAuth);
// Get Authentication type
com.beasys.Tobj.AuthType authType = auth.get_auth_type();
// Initialize arguments
String userName = "John";
String clientName = "Teller";
String systemPassword = null;
String userPassword = null;
byte[] userData = new byte[0];
// Prepare arguments according to security level requested
switch(authType.value())
{
case com.beasys.Tobj.AuthType._TPNOAUTH:
break;
case com.beasys.Tobj.AuthType._TPSYSAUTH:
systemPassword = "sys_pw";
break;
case com.beasys.Tobj.AuthType._TPAPPAUTH:
systemPassword = "sys_pw";
userPassword = "john_pw";
break;
}
// TUXEDO-style Authentication
org.omg.Security.AuthenticationStatus status =
auth.logon(userName, clientName, systemPassword,
userPassword, userData);
...
// Proceed with application
// Log off
try
{
auth.logoff();
}
...
This section describes implementing certificate-based authentication in WLE applications.
The Secure Simpapp sample application uses the existing Simpapp sample application and modifies the code and configuration files to support secure communications through the SSL protocol and certificate-based authentication.
The server application in the secure Simpapp sample application provides an implementation of a CORBA object that has the following two methods:
Figure 5-2 illustrates how the Secure Simpapp sample application works.
The Simpapp sample application was modified in the following ways to support certificate-based authentication and the SSL protocol:
The source files for the C++ and Java versions of the Secure Simpapp sample application are located in the \samples\corba\simpappSSL
and \samples\corba\simpappSSL_java
directories of the WLE software. For instructions for building and running the Secure Simpapp sample application, see Building and Running the CORBA Sample Applications.
When using certificate-based authentication, write client application code that does the following:
Writing the Client Application
The following sections contain C++ and Java code examples that illustrate implementing certificate-based authentication.
Listing 5-7 illustrates using certificate-based authentication in a C++ client application.
Listing 5-7 C++ Client Application That Uses Certificate-Based Authentication
....
// Initialize the ORB
CORBA::ORB_var v_orb = CORBA::ORB_init(argc, argv, "");
// Create the bootstrap object
Tobj_Bootstrap bootstrap(v_orb.in(), corbalocs://sling.com:2143);
// Resolve SecurityCurrent
CORBA::Object_ptr seccurobj =
bootstrap.resolve_initial_references("SecurityCurrent");
SecurityLevel2::Current_ptr seccur =
SecurityLevel2::Current::_narrow(seccurobj);
// Perform certificate-based authentication
SecurityLevel2::Credentials_ptr the_creds;
Security::AttributeList_var privileges;
Security::Opaque_var continuation_data;
Security::Opaque_var auth_specific_data;
Security::Opaque_var response_data;
//Principal email address
char emailAddress[] = "milozzi@bigcompany.com;"
// Pass phrase for principal's digital certificate
char password[] = "asdawrewe98infldi7;"
// Convert the certificate private key password to opaque
unsigned long password_len = strlen(password);
Security::Opaque ssl_auth_data(password_len);
// Authenticate principal certificate with principal authenticator
for(int i = 0; (unsigned long) i < password_len; i++)
ssl_auth_data[i] = password[i];
Security::AuthenticationStatus auth_status;
SecurityLevel2::PrincipalAuthenticator_var PA =
seccur->principal_authenticator();
auth_status = PA->authenticate(Tobj::CertificateBased,
emailAddress,
ssl_auth_data,
privileges,
the_creds,
continuation_data,
auth_specific_data);
while(auth_status == Security::SecAuthContinue) {
auth_status = PA->continue_authentication(
response_data,
the_creds,
continuation_data,
auth_specific_data);
}
...
Listing 5-8 illustrates using certificate-based authentication in a C++ client application.
Listing 5-8 Java Client Application That Uses Certificate-based Authentication
...
// Initialize the ORB.
Properties Prop;
Prop = new Properties(System.getProperties());
Prop.put("org.omg.CORBA.ORBClass","com.beasys.CORBA.iiop.ORB");
Prop.put("org.omg.CORBA.ORBSingletonClass",
"com.beasys.CORBA.idl.ORBSingleton");
ORB orb = ORB.init(args, Prop);
// Create the Bootstrap object
Tobj_Bootstrap bs = new Tobj_Bootstrap(orb,
corbalocs://foo:2501);
//Resolve SecurityCurrent
org.omg.CORBA.object ocurr =
bs.resolve_initial_references("SecurityCurrent");
org.omg.SecurityLevel2.Current curr =
org.omg.SecurityLevel2.CurrentHelper.narrow(occur);
// Get Principal Authenticator
com.beasys.Tobj.PrincipalAuthenticator pa =
(com.beasys.Tobj.PrincipalAuthenticator)
curr.principal_authenticator();
OpaqueHolder auth_data = new OpaqueHolder();
AttributeListHolder privileges = new AttributeListHolder();
org.omg.SecurityLevel2.CredentialsHolder creds =
new org.omg.SecurityLevel2.CredentialsHolder();
OpaqueHolder continuation_data = new OpaqueHolder();
OpaqueHolder auth_specific_data = new OpaqueHolder();
auth_data.value=new String ("deathstar").getbytes("UTF8);
if(pa.authenticate(com.beasys.Tobj.CertificateBased.value,
"vader@largecompany.com",
auth_data.value,
privileges.value,
the_creds,
continuation_data,
auth_specific_data)
!AuthenticationStatus.SecAuthSuccess) {
System.err.println("logon failed");
System.exit(1);
}
...
When using certificate-based authentication, it may be necessary for a principal to explicitly define the security attributes it requires. For example, a bank application may have specific security requirements it needs met before the bank application can transfer data to a database. The invocation_options_required() method of the SecurityLevel2::Credentials interface allows the principal to explicitly control the security characteristics of the SSL connection. When using the corbaloc URL address format, you can secure the bootstrapping process by using the authenticate() and invocation_options_required() methods of the SecurityLevel2::Credentials interface.
Perform the following steps to use the invocation_options_required() method :
Listing 5-9 provides a C++ example of using the invocation_options_required() method.
Listing 5-9 C++ Example of Using the invocation_options_required() Method
// Initialize the ORB
CORBA::ORB_var v_orb = CORBA::ORB_init(argc, argv, "");
// Create the bootstrap object
Tobj_Bootstrap bootstrap(v_orb.in(), corbalocs://sling.com:2143);
// Resolve SecurityCurrent
CORBA::Object_ptr seccurobj =
bootstrap.resolve_initial_references("SecurityCurrent");
SecurityLevel2::Current_ptr seccur =
SecurityLevel2::Current::_narrow(seccurobj);
// Perform certificate-based authentication
SecurityLevel2::Credentials_ptr the_creds;
Security::AttributeList_var privileges;
Security::Opaque_var continuation_data;
Security::Opaque_var auth_specific_data;
Security::Opaque_var response_data;
//Principal email address
char emailAddress[] = "milozzi@bigcompany.com;"
// Pass phrase for principal's digital certificate
char password[] = "asdawrewe98infldi7;"
// Convert the certificate private key password to opaque
unsigned long password_len = strlen(password);
Security::Opaque ssl_auth_data(password_len);
// Authenticate principal certificate with principal authenticator
for(int i = 0; (unsigned long) i < password_len; i++)
ssl_auth_data[i] = password[i];
Security::AuthenticationStatus auth_status;
SecurityLevel2::PrincipalAuthenticator_var PA =
seccur->principal_authenticator();
auth_status = PA->authenticate(Tobj::CertificateBased,
emailAddress,
ssl_auth_data,
privileges,
the_creds,
continuation_data,
auth_specific_data);
the_creds->invocation_options_required(
Security::Integrity|
Security::DetectReplay|
Security::DetectMisordering|
Security::EstablishTrustInTarget|
Security::EstalishTrustInClient|
Security::SimpleDelegation);
while(auth_status == Security::SecAuthContinue) {
auth_status = PA->continue_authentication(
response_data,
the_creds,
continuation_data,
auth_specific_data);
}
...
Listing 5-10 provdes a Java example of using the invocation_options_required() method
Listing 5-10 Java Example of Using the invocation_options_required() Method
...
// Initialize the ORB.
Properties Prop;
Prop = new Properties(System.getProperties());
Prop.put("org.omg.CORBA.ORBClass","com.beasys.CORBA.iiop.ORB");
Prop.put("org.omg.CORBA.ORBSingletonClass",
"com.beasys.CORBA.idl.ORBSingleton");
ORB orb = ORB.init(args, Prop);
// Create the Bootstrap object
Tobj_Bootstrap bs = new Tobj_Bootstrap(orb,
corbalocs://foo:2501);
//Resolve SecurityCurrent
org.omg.CORBA.object ocurr =
bs.resolve_initial_references("SecurityCurrent");
org.omg.SecurityLevel2.Current curr =
org.omg.SecurityLevel2.CurrentHelper.narrow(occur);
// Get Principal Authenticator
com.beasys.Tobj.PrincipalAuthenticator pa =
(com.beasys.Tobj.PrincipalAuthenticator)
curr.principal_authenticator();
OpaqueHolder auth_data = new OpaqueHolder();
AttributeListHolder privileges = new AttributeListHolder();
org.omg.SecurityLevel2.CredentialsHolder creds =
new org.omg.SecurityLevel2.CredentialsHolder();
OpaqueHolder continuation_data = new OpaqueHolder();
OpaqueHolder auth_specific_data = new OpaqueHolder();
auth_data.value=new String ("deathstar").getbytes("UTF8);
if(pa.authenticate(com.beasys.Tobj.CertificateBased.value,
"vader@largecompany.com",
auth_data.value,
privileges.value,
the_creds,
continuation_data,
auth_specific_data)
org.omg.SecurityLevel2.Credentials credentials = curr.get_credentials(
org.omg.Security.CredentialType.SecInvocationCredentials);
credentials.invocation_options_required(
(short) (org.omg.Security.Integrity.value |
org.omg.Security.DetectReplay.value|
org.omg.Security.DetectMisordering.value|
org.omg.Security.EstablishTrustInTarget.value|
org.omg.Security.EstablishTrustInClient.value|
org.omg.Security.SimpleDelegation.value)
);
!AuthenticationStatus.SecAuthSuccess) {
System.err.println("logon failed");
System.exit(1);
}
...
|
Copyright © 1999 BEA Systems, Inc. All rights reserved.
|