package org.jboss.iiop.csiv2;
import org.omg.CORBA.Any;
import org.omg.CORBA.BAD_PARAM;
import org.omg.CORBA.MARSHAL;
import org.omg.CORBA.NO_PERMISSION;
import org.omg.CORBA.LocalObject;
import org.omg.CORBA.ORB;
import org.omg.CSI.CompleteEstablishContext;
import org.omg.CSI.ContextError;
import org.omg.CSI.EstablishContext;
import org.omg.CSI.GSS_NT_ExportedNameHelper;
import org.omg.CSI.ITTPrincipalName;
import org.omg.CSI.IdentityToken;
import org.omg.CSI.MTEstablishContext;
import org.omg.CSI.MTMessageInContext;
import org.omg.CSI.SASContextBody;
import org.omg.CSI.SASContextBodyHelper;
import org.omg.GSSUP.ErrorToken;
import org.omg.GSSUP.ErrorTokenHelper;
import org.omg.GSSUP.GSS_UP_S_G_UNSPECIFIED;
import org.omg.GSSUP.InitialContextToken;
import org.omg.IOP.Codec;
import org.omg.IOP.CodecPackage.FormatMismatch;
import org.omg.IOP.CodecPackage.TypeMismatch;
import org.omg.IOP.CodecPackage.InvalidTypeForEncoding;
import org.omg.IOP.ServiceContext;
import org.omg.PortableInterceptor.ServerRequestInfo;
import org.omg.PortableInterceptor.ServerRequestInterceptor;
import org.jboss.iiop.CorbaORBService;
import org.jboss.logging.Logger;
public class SASTargetInterceptor
extends LocalObject
implements ServerRequestInterceptor
{
static final long serialVersionUID = 3352317126682935627L;
private static final Logger log =
Logger.getLogger(SASTargetInterceptor.class);
private static final boolean traceEnabled = log.isTraceEnabled();
private static final int sasContextId =
org.omg.IOP.SecurityAttributeService.value;
private static final byte[] empty = new byte[0];
private static final IdentityToken absent;
private static final SASContextBody msgBodyCtxAccepted;
private static final Any msgCtx0Accepted;
static
{
absent = new IdentityToken();
absent.absent(true);
CompleteEstablishContext ctxAccepted =
new CompleteEstablishContext(0,
false,
new byte[0] );
msgBodyCtxAccepted = new SASContextBody();
msgBodyCtxAccepted.complete_msg(ctxAccepted);
msgCtx0Accepted = createMsgCtxAccepted(0);
}
private static Any createMsgCtxAccepted(long contextId)
{
Any any = ORB.init().create_any();
synchronized (msgBodyCtxAccepted)
{
msgBodyCtxAccepted.complete_msg().client_context_id = contextId;
SASContextBodyHelper.insert(any, msgBodyCtxAccepted);
}
return any;
}
private final Codec codec;
private final SASContextBody msgBodyCtxError;
private final Any msgCtx0Rejected;
private ThreadLocal threadLocalData = new ThreadLocal() {
protected synchronized Object initialValue()
{
return new CurrentRequestInfo(); }
};
private static class CurrentRequestInfo
{
boolean sasContextReceived;
boolean authenticationTokenReceived;
byte[] incomingUsername;
byte[] incomingPassword;
byte[] incomingTargetName;
IdentityToken incomingIdentity;
byte[] incomingPrincipalName;
long contextId;
Any sasReply;
boolean sasReplyIsAccept; CurrentRequestInfo()
{
}
}
private Any createMsgCtxError(long contextId, int majorStatus)
{
Any any = ORB.init().create_any();
synchronized (msgBodyCtxError)
{
msgBodyCtxError.error_msg().client_context_id = contextId;
msgBodyCtxError.error_msg().major_status = majorStatus;
SASContextBodyHelper.insert(any, msgBodyCtxError);
}
return any;
}
public SASTargetInterceptor(Codec codec)
{
this.codec = codec;
ErrorToken errorToken = new ErrorToken(GSS_UP_S_G_UNSPECIFIED.value);
Any any = ORB.init().create_any();
byte[] encapsulatedErrorToken;
ErrorTokenHelper.insert(any, errorToken);
try
{
encapsulatedErrorToken = codec.encode_value(any);
}
catch (InvalidTypeForEncoding e)
{
throw new RuntimeException("Unexpected exception: " + e);
}
ContextError ctxError =
new ContextError(0,
1,
1,
encapsulatedErrorToken);
msgBodyCtxError = new SASContextBody();
msgBodyCtxError.error_msg(ctxError);
msgCtx0Rejected = createMsgCtxError(0, 1);
}
boolean sasContextReceived()
{
CurrentRequestInfo threadLocal =
(CurrentRequestInfo)threadLocalData.get();
return threadLocal.sasContextReceived;
}
boolean authenticationTokenReceived()
{
CurrentRequestInfo threadLocal =
(CurrentRequestInfo)threadLocalData.get();
return threadLocal.authenticationTokenReceived;
}
byte[] getIncomingUsername()
{
CurrentRequestInfo threadLocal =
(CurrentRequestInfo)threadLocalData.get();
return threadLocal.incomingUsername;
}
byte[] getIncomingPassword()
{
CurrentRequestInfo threadLocal =
(CurrentRequestInfo)threadLocalData.get();
return threadLocal.incomingPassword;
}
byte[] getIncomingTargetName()
{
CurrentRequestInfo threadLocal =
(CurrentRequestInfo)threadLocalData.get();
return threadLocal.incomingTargetName;
}
IdentityToken getIncomingIdentity()
{
CurrentRequestInfo threadLocal =
(CurrentRequestInfo)threadLocalData.get();
return threadLocal.incomingIdentity;
}
byte[] getIncomingPrincipalName()
{
CurrentRequestInfo threadLocal =
(CurrentRequestInfo)threadLocalData.get();
return threadLocal.incomingPrincipalName;
}
void rejectIncomingContext()
{
CurrentRequestInfo threadLocal =
(CurrentRequestInfo)threadLocalData.get();
if (threadLocal.sasContextReceived)
{
threadLocal.sasReply =
(threadLocal.contextId == 0)
? msgCtx0Rejected
: createMsgCtxError(threadLocal.contextId,
1 );
threadLocal.sasReplyIsAccept = false;
}
}
public String name()
{
return "SASTargetInterceptor";
}
public void destroy()
{
}
public void receive_request_service_contexts(ServerRequestInfo ri)
{
}
public void receive_request(ServerRequestInfo ri)
{
if (traceEnabled)
log.trace("receive_request " + ri.operation());
CurrentRequestInfo threadLocal =
(CurrentRequestInfo)threadLocalData.get();
threadLocal.sasContextReceived = false;
threadLocal.authenticationTokenReceived = false;
threadLocal.incomingUsername = empty;
threadLocal.incomingPassword = empty;
threadLocal.incomingTargetName = empty;
threadLocal.incomingIdentity = absent;
threadLocal.incomingPrincipalName = empty;
threadLocal.sasReply = null;
threadLocal.sasReplyIsAccept = false;
try
{
ServiceContext sc = ri.get_request_service_context(sasContextId);
Any any = codec.decode_value(sc.context_data,
SASContextBodyHelper.type());
SASContextBody contextBody = SASContextBodyHelper.extract(any);
if (contextBody == null)
{
return;
}
else if (contextBody.discriminator() == MTMessageInContext.value)
{
long contextId =
contextBody.in_context_msg().client_context_id;
threadLocal.sasReply =
createMsgCtxError(contextId,
4 );
throw new NO_PERMISSION("SAS context does not exist.");
}
else if (contextBody.discriminator() == MTEstablishContext.value)
{
EstablishContext message = contextBody.establish_msg();
threadLocal.contextId = message.client_context_id;
threadLocal.sasContextReceived = true;
if (message.client_authentication_token != null
&& message.client_authentication_token.length > 0)
{
if (traceEnabled)
log.trace("received client authentication token");
InitialContextToken authToken =
CSIv2Util.decodeInitialContextToken(
message.client_authentication_token,
codec);
if (authToken == null)
{
threadLocal.sasReply =
createMsgCtxError(message.client_context_id,
2 );
throw new NO_PERMISSION("Could not decode " +
"initial context token.");
}
threadLocal.incomingUsername = authToken.username;
threadLocal.incomingPassword = authToken.password;
threadLocal.incomingTargetName =
CSIv2Util.decodeGssExportedName(authToken.target_name);
if (threadLocal.incomingTargetName == null)
{
threadLocal.sasReply =
createMsgCtxError(message.client_context_id,
2 );
throw new NO_PERMISSION("Could not decode target name " +
"in initial context token.");
}
threadLocal.authenticationTokenReceived = true;
}
if (message.identity_token != null)
{
if (traceEnabled)
log.trace("received identity token");
threadLocal.incomingIdentity = message.identity_token;
if (message.identity_token.discriminator() == ITTPrincipalName.value)
{
Any a = codec.decode_value(
message.identity_token.principal_name(),
GSS_NT_ExportedNameHelper.type());
byte[] encodedName = GSS_NT_ExportedNameHelper.extract(a);
threadLocal.incomingPrincipalName =
CSIv2Util.decodeGssExportedName(encodedName);
if (threadLocal.incomingPrincipalName == null)
{
threadLocal.sasReply =
createMsgCtxError(message.client_context_id,
2 );
throw new NO_PERMISSION("Could not decode " +
"incoming principal name.");
}
}
}
threadLocal.sasReply = (threadLocal.contextId == 0) ?
msgCtx0Accepted :
createMsgCtxAccepted(threadLocal.contextId);
threadLocal.sasReplyIsAccept = true;
}
}
catch (BAD_PARAM e)
{
}
catch (FormatMismatch e)
{
throw new MARSHAL("Exception decoding context data in " +
"SASTargetInterceptor: " + e);
}
catch (TypeMismatch e)
{
throw new MARSHAL("Exception decoding context data in " +
"SASTargetInterceptor: " + e);
}
}
public void send_reply(ServerRequestInfo ri)
{
if (traceEnabled)
log.trace("send_reply " + ri.operation());
CurrentRequestInfo threadLocal =
(CurrentRequestInfo)threadLocalData.get();
if (threadLocal.sasReply != null)
{
try
{
ServiceContext sc =
new ServiceContext(sasContextId,
codec.encode_value(threadLocal.sasReply));
ri.add_reply_service_context(sc, true);
}
catch (InvalidTypeForEncoding e)
{
throw new MARSHAL("Unexpected exception: " + e);
}
}
}
public void send_exception(ServerRequestInfo ri)
{
if (traceEnabled)
log.trace("send_exception " + ri.operation() + ": ");
CurrentRequestInfo threadLocal =
(CurrentRequestInfo)threadLocalData.get();
if (threadLocal.sasReply != null &&
(!threadLocal.sasReplyIsAccept ||
CorbaORBService.getSendSASAcceptWithExceptionEnabledFlag() == true))
{
try
{
ServiceContext sc =
new ServiceContext(sasContextId,
codec.encode_value(threadLocal.sasReply));
ri.add_reply_service_context(sc, true);
}
catch (InvalidTypeForEncoding e)
{
throw new MARSHAL("Unexpected exception: " + e);
}
}
}
public void send_other(ServerRequestInfo ri)
{
}
}