SecClientRequestInterceptorpublic class SecClientRequestInterceptor extends org.omg.CORBA.LocalObject implements ClientRequestInterceptorThis class implements a client side security request interceptor for CSIV2.
It is used to send and receive the service context in a service context
element in the service context list in an IIOP header. |
Fields Summary |
---|
private static Logger | _logger | private static com.sun.enterprise.util.LocalStringManagerImpl | localStrings | private String | name | private String | prnameprname (name + "::") is name of interceptor used for logging
purposes. It is only used in the call to Logger.methodentry()
in this file. Its purpose is to identify the interceptor name | private Codec | codec | private ORB | orb | private SecurityService | secsvc | protected static final int | SECURITY_ATTRIBUTE_SERVICE_IDHard code the value of 15 for SecurityAttributeService until
it is defined in IOP.idl.
sc.context_id = SecurityAttributeService.value; |
Constructors Summary |
---|
public SecClientRequestInterceptor(String name, Codec codec)
this.name = name;
this.codec = codec;
this.prname = name + "::";
|
Methods Summary |
---|
private byte[] | createAuthToken(java.lang.Object cred, java.lang.Class cls)Returns a client authentication token for the
PasswordCredential in the subject.
The client authentication token is cdr encoded.
byte[] gsstoken = {}; // GSS token
if (PasswordCredential.class.isAssignableFrom(cls)) {
_logger.log(Level.FINE,"Constructing a PasswordCredential client auth token");
/* Generate mechanism specific GSS token for the GSSUP mechanism */
PasswordCredential pwdcred = (PasswordCredential) cred;
GSSUPToken tok = GSSUPToken.getClientSideInstance(orb, codec, pwdcred);
gsstoken = tok.getGSSToken();
}
return gsstoken;
| private IdentityToken | createIdToken(java.lang.Object cred, java.lang.Class cls)create and return an identity token from the credential.
The identity token is cdr encoded.
IdentityToken idtok = null;
DerOutputStream dos = new DerOutputStream();
DerValue[] derval = {} ; // DER encoding buffer
byte[] cdrval ; // CDR encoding buffer
Any any = orb.create_any();
idtok = new IdentityToken();
if (X500Name.class.isAssignableFrom(cls)) {
_logger.log(Level.FINE,"Constructing an X500 DN Identity Token");
X500Name name = (X500Name) cred;
name.encode(dos); // ASN.1 encoding
X501DistinguishedNameHelper.insert(any, dos.toByteArray());
/* IdentityToken with CDR encoded X501 name */
idtok.dn(codec.encode_value(any));
} else if (X509CertificateCredential.class.isAssignableFrom(cls)) {
_logger.log(Level.FINE,"Constructing an X509 Certificate Chain Identity Token");
/* create a DER encoding */
X509CertificateCredential certcred = (X509CertificateCredential) cred;
X509Certificate[] certchain = certcred.getX509CertificateChain();
_logger.log(Level.FINE,"Certchain length = " + certchain.length);
derval = new DerValue[certchain.length];
for (int i = 0; i < certchain.length ; i++)
derval[i] = new DerValue(certchain[i].getEncoded());
dos.putSequence(derval);
X509CertificateChainHelper.insert(any, dos.toByteArray());
/* IdentityToken with CDR encoded certificate chain */
idtok.certificate_chain(codec.encode_value(any));
} else if (AnonCredential.class.isAssignableFrom(cls)) {
_logger.log(Level.FINE,"Constructing an Anonymous Identity Token");
idtok.anonymous(true);
} else if (GSSUPName.class.isAssignableFrom(cls)) {
/* GSSAPI Exported name */
_logger.log(Level.FINE,"Constructing a GSS Exported name Identity Token");
/* create a DER encoding */
GSSUPName gssname = (GSSUPName) cred;
byte[] expname = gssname.getExportedName();
GSS_NT_ExportedNameHelper.insert(any, expname);
/* IdentityToken with CDR encoded GSSUPName */
idtok.principal_name(codec.encode_value(any));
}
return (idtok);
| public void | destroy()
| private java.lang.Object | getCred(java.util.Set credset, java.lang.Class c)Retrieves a single credential from a credset for the specified class.
It also performs some semantic checking and logging.
A null is returned if semantic checking fails.
java.lang.Object cred = null ; // return value
String clsname = c.getName() ;
/* check that there is only instance of a credential in the subject */
if(_logger.isLoggable(Level.FINE)) {
_logger.log(Level.FINE,"Checking for a single instance of class in subject");
_logger.log(Level.FINE," Classname = " + clsname);
}
if (credset.size() != 1) {
if(_logger.isLoggable(Level.SEVERE))
_logger.log(Level.SEVERE,"iiop.multiple_credset",new java.lang.Object[]{new Integer(credset.size()),clsname});
throw new SecurityException(
localStrings.getLocalString("secclientreqinterceptor.inv_credlist_size",
"Credential list size is not 1."));
}
Iterator iter = credset.iterator();
while (iter.hasNext())
cred = iter.next();
if(_logger.isLoggable(Level.FINE))
_logger.log(Level.FINE,"Verified single instance of class ( " +clsname + " )");
return cred;
| private void | handle_null_service_context(ClientRequestInfo ri)
if(_logger.isLoggable(Level.FINE)){
_logger.log(Level.FINE,"No SAS context element found in service context list");
}
setreplyStatus(SecurityService.STATUS_PASSED, ri.effective_target());
| private int | mapreplyStatus(int repst)Map the reply status code to a format suitable for J2EE RI.
int status;
if(_logger.isLoggable(Level.FINE)){
_logger.log(Level.FINE,"Reply status to be mapped = " + repst);
}
switch (repst) {
case SUCCESSFUL.value:
case USER_EXCEPTION.value:
status = SecurityService.STATUS_PASSED;
break;
case LOCATION_FORWARD.value:
case TRANSPORT_RETRY.value:
status = SecurityService.STATUS_RETRY;
break;
case SYSTEM_EXCEPTION.value:
status = SecurityService.STATUS_FAILED;
break;
default:
status = repst;
/**
* There is currently no mapping defined for any other status
* codes. So map this is to a STATUS_FAILED.
*/
break;
}
if(_logger.isLoggable(Level.FINE)){
_logger.log(Level.FINE,"Mapped reply status = " + status);
}
return status;
| public java.lang.String | name()
return name;
| public void | receive_exception(ClientRequestInfo ri)
if(_logger.isLoggable(Level.FINE)){
_logger.log(Level.FINE,"++++ Entered " + prname + "receive_exception");
}
| public void | receive_other(ClientRequestInfo ri)
| public void | receive_reply(ClientRequestInfo ri)
ServiceContext sc = null;
int status = -1;
if(_logger.isLoggable(Level.FINE)){
_logger.log(Level.FINE,"++++ Entered " + prname + "receive_reply");
}
orb = ORBManager.getORB();
/**
* get the service context element from the reply and decode the
* mesage.
*/
try {
sc = ri.get_reply_service_context(SECURITY_ATTRIBUTE_SERVICE_ID);
if (sc == null) {
handle_null_service_context(ri);
return;
}
} catch(org.omg.CORBA.BAD_PARAM e) {
handle_null_service_context(ri);
return;
} catch(Exception ex) {
_logger.log(Level.SEVERE,"iiop.service_context_exception",ex);
return;
}
Any a = orb.create_any();
try {
a = codec.decode_value(sc.context_data, SASContextBodyHelper.type()); //decode the CDR encoding
} catch (Exception e) {
_logger.log(Level.SEVERE,"iiop.decode_exception",e);
throw new SecurityException(
localStrings.getLocalString("secclientreqinterceptor.err_cdr_decode",
"CDR Decoding error for SAS context element."));
}
SASContextBody sasctxbody = SASContextBodyHelper.extract(a);
short sasdiscr = sasctxbody.discriminator();
if(_logger.isLoggable(Level.FINE)){
_logger.log(Level.FINE,"Received " + SvcContextUtils.getMsgname(sasdiscr) + " message");
}
/**
* Verify that either a CompleteEstablishContext msg or an
* ContextError message was received.
*/
if(_logger.isLoggable(Level.FINE)){
_logger.log(Level.FINE,"Verifying the SAS protocol reply message");
}
/* Check the discriminator value */
if ((sasdiscr != MTCompleteEstablishContext.value)
&& (sasdiscr != MTContextError.value)) {
_logger.log(Level.SEVERE,"iiop.invalid_reply_message");
throw new SecurityException(
localStrings.getLocalString("secclientreqinterceptor.err_not_cecec_msg",
"Reply message not one of CompleteEstablishContext or ContextError."));
}
/* Map the error code */
int st = mapreplyStatus(ri.reply_status());
setreplyStatus(st, ri.effective_target());
| public void | send_poll(ClientRequestInfo ri)
| public void | send_request(ClientRequestInfo ri)send_request() interception point adds the security context to the
service context field.
/**
* CSIV2 level 0 implementation only requires stateless clients.
* Client context id is therefore always set to 0.
*/
long cContextId = 0; // CSIV2 requires type to be long
/**
* CSIV2 level 0 implementation does not require any authorization
* tokens to be sent over the wire. So set cAuthzElem to empty.
*/
AuthorizationElement[] cAuthzElem = {} ;
/* Client identity token to be added to the service context field */
IdentityToken cIdentityToken = null;
/* Client authentication token to be added to the service context field */
byte[] cAuthenticationToken = {} ;
/* CDR encoded Security Attribute Service element */
byte[] cdr_encoded_saselm = {} ;
java.lang.Object cred = null ; // A single JAAS credential
if(_logger.isLoggable(Level.FINE))
_logger.log(Level.FINE,"++++ Entered " + prname + "send_request" + "()");
SecurityContext secctxt = null; // SecurityContext to be sent
secsvc = Csiv2Manager.getSecurityService();
orb = ORBManager.getORB();
if (secsvc == null) {
_logger.log(Level.WARNING,"iiop.no_security_service");
return;
}
org.omg.CORBA.Object effective_target = ri.effective_target();
try{
secctxt = secsvc.getSecurityContext(effective_target);
}catch(InvalidMechanismException ime){
_logger.log(Level.SEVERE,"iiop.sec_context_exception",ime);
throw new RuntimeException(ime.getMessage());
}catch(InvalidIdentityTokenException iite){
_logger.log(Level.SEVERE,"iiop.runtime_exception",iite);
throw new RuntimeException(iite.getMessage());
}
/**
* In an unprotected invocation, there is nothing to be sent to
* the service context field. Check for this case.
*/
if (secctxt == null) {
if(_logger.isLoggable(Level.FINE)){
_logger.log(Level.FINE,"Security context is null (nothing to add to service context)");
}
return;
}
final SecurityContext sCtx = secctxt;
/* Construct an authentication token */
if (secctxt.authcls != null) {
cred = AccessController.doPrivileged(new PrivilegedAction() {
public java.lang.Object run() {
return getCred(sCtx.subject.getPrivateCredentials(sCtx.authcls), sCtx.authcls);
}
});
try {
cAuthenticationToken = createAuthToken(cred, secctxt.authcls);
} catch (Exception e) {
_logger.log(Level.SEVERE,"iiop.createauthtoken_exception",e);
throw new SecurityException(
localStrings.getLocalString("secclientreqinterceptor.err_authtok_create",
"Error while constructing an authentication token."));
}
}
/* Construct an identity token */
if (secctxt.identcls != null) {
cred = getCred(secctxt.subject.getPublicCredentials(secctxt.identcls),
secctxt.identcls);
try {
cIdentityToken = createIdToken(cred, secctxt.identcls);
} catch (Exception e) {
_logger.log(Level.SEVERE,"iiop.createidtoken_exception",e);
throw new SecurityException(
localStrings.getLocalString("secclientreqinterceptor.err_idtok_create",
"Error while constructing an identity token."));
}
} else {
if(_logger.isLoggable(Level.FINE)){
_logger.log(Level.FINE,"Constructing an Absent Identity Token");
}
cIdentityToken = new IdentityToken();
cIdentityToken.absent(true);
}
if(_logger.isLoggable(Level.FINE)){
_logger.log(Level.FINE,"Creating an EstablishContext message");
}
EstablishContext ec = new EstablishContext(cContextId,
cAuthzElem,
cIdentityToken,
cAuthenticationToken);
SASContextBody sasctxbody = new SASContextBody();
sasctxbody.establish_msg(ec);
/* CDR encode the SASContextBody */
Any SasAny = orb.create_any();
SASContextBodyHelper.insert(SasAny, sasctxbody);
try {
cdr_encoded_saselm = codec.encode_value(SasAny);
} catch (Exception e) {
_logger.log(Level.SEVERE,"iiop.encode_exception",e);
throw new SecurityException(
localStrings.getLocalString("secclientreqinterceptor.err_cdr_encode",
"CDR Encoding error for a SAS context element."));
}
/* add SAS element to service context list*/
ServiceContext sc = new ServiceContext();
sc.context_id = SECURITY_ATTRIBUTE_SERVICE_ID;
sc.context_data = cdr_encoded_saselm;
if(_logger.isLoggable(Level.FINE)){
_logger.log(Level.FINE,"Adding EstablishContext message to service context list");
}
boolean no_replace = false;
ri.add_request_service_context(sc, no_replace);
if(_logger.isLoggable(Level.FINE)){
_logger.log(Level.FINE,"Added EstablishContext message to service context list");
}
| private void | setreplyStatus(int status, org.omg.CORBA.Object target)set the reply status
if(_logger.isLoggable(Level.FINE)){
_logger.log(Level.FINE,"Status to be set : " + status);
}
secsvc = Csiv2Manager.getSecurityService();
if (secsvc == null) {
_logger.log(Level.WARNING,"iiop.no_security_service");
return;
}
secsvc.receivedReply(status, target);
if(_logger.isLoggable(Level.FINE)){
_logger.log(Level.FINE,"Invoked receivedReply()");
}
|
|