package org.jboss.security.jacc;
import java.security.CodeSource;
import java.security.Permission;
import java.security.PermissionCollection;
import java.security.Policy;
import java.security.ProtectionDomain;
import java.util.Iterator;
import java.util.Enumeration;
import javax.security.jacc.EJBMethodPermission;
import javax.security.jacc.EJBRoleRefPermission;
import javax.security.jacc.PolicyConfiguration;
import javax.security.jacc.PolicyContext;
import javax.security.jacc.PolicyContextException;
import javax.security.jacc.WebResourcePermission;
import javax.security.jacc.WebRoleRefPermission;
import javax.security.jacc.WebUserDataPermission;
import javax.security.auth.Subject;
import org.jboss.logging.Logger;
import EDU.oswego.cs.dl.util.concurrent.ConcurrentReaderHashMap;
public class DelegatingPolicy extends Policy
{
private static Logger log = Logger.getLogger(DelegatingPolicy.class);
private static DelegatingPolicy instance;
private Policy delegate;
private ConcurrentReaderHashMap activePolicies = new ConcurrentReaderHashMap();
private ConcurrentReaderHashMap openPolicies = new ConcurrentReaderHashMap();
private boolean trace;
private PolicyProxy policyProxy = new PolicyProxy(this);
public synchronized static DelegatingPolicy getInstance()
{
if (instance == null)
{
instance = new DelegatingPolicy();
}
return instance;
}
public DelegatingPolicy()
{
this(null);
}
public DelegatingPolicy(Policy delegate)
{
if (delegate == null)
delegate = Policy.getPolicy();
this.delegate = delegate;
this.trace = log.isTraceEnabled();
if (instance == null)
instance = this;
Permission permission = new RuntimePermission("test");
boolean loadedPerms = !(permission instanceof EJBMethodPermission
|| permission instanceof EJBRoleRefPermission
|| permission instanceof WebResourcePermission
|| permission instanceof WebRoleRefPermission
|| permission instanceof WebUserDataPermission);
if (trace)
log.trace("Loaded JACC permissions: " + loadedPerms);
Class c = PolicyContext.class;
}
public PermissionCollection getPermissions(ProtectionDomain domain)
{
PermissionCollection pc = super.getPermissions(domain);
PermissionCollection delegated = delegate.getPermissions(domain);
for (Enumeration e = delegated.elements(); e.hasMoreElements();)
{
Permission p = (Permission) e.nextElement();
pc.add(p);
}
return pc;
}
public boolean implies(ProtectionDomain domain, Permission permission)
{
boolean isJaccPermission = permission instanceof EJBMethodPermission
|| permission instanceof EJBRoleRefPermission
|| permission instanceof WebResourcePermission
|| permission instanceof WebRoleRefPermission
|| permission instanceof WebUserDataPermission;
if (trace)
{
log.trace("implies, domain=" + domain + ", permission=" + permission
+ ", isJaccPermission=" + isJaccPermission);
try
{
Subject caller = (Subject) PolicyContext.getContext("javax.security.auth.Subject.container");
log.trace("implies javax.security.auth.Subject.container: "+caller);
}
catch(Throwable e)
{
log.trace("Failed to access Subject context", e);
}
}
boolean implied = false;
if (isJaccPermission == false)
{
implied = delegate.implies(domain, permission);
}
else
{
String contextID = PolicyContext.getContextID();
ContextPolicy contextPolicy = (ContextPolicy) activePolicies.get(contextID);
if (contextPolicy != null)
implied = contextPolicy.implies(domain, permission);
else if (trace)
log.trace("No PolicyContext found for contextID=" + contextID);
}
if (trace)
{
log.trace("implied=" + implied);
}
return implied;
}
public PermissionCollection getPermissions(CodeSource cs)
{
PermissionCollection pc = null;
String contextID = PolicyContext.getContextID();
if (contextID == null)
{
pc = delegate.getPermissions(cs);
}
else
{
ContextPolicy policy = (ContextPolicy) activePolicies.get(contextID);
if (policy != null)
{
pc = policy.getPermissions();
}
else
{
pc = delegate.getPermissions(cs);
}
}
return pc;
}
public void refresh()
{
}
public Policy getPolicyProxy()
{
return policyProxy;
}
public String listContextPolicies()
{
StringBuffer tmp = new StringBuffer("<ActiveContextPolicies>");
Iterator iter = activePolicies.keySet().iterator();
while (iter.hasNext())
{
String contextID = (String) iter.next();
ContextPolicy cp = (ContextPolicy) activePolicies.get(contextID);
tmp.append(cp);
tmp.append('\n');
}
tmp.append("</ActiveContextPolicies>");
tmp.append("<OpenContextPolicies>");
iter = openPolicies.keySet().iterator();
while (iter.hasNext())
{
String contextID = (String) iter.next();
ContextPolicy cp = (ContextPolicy) openPolicies.get(contextID);
tmp.append(cp);
tmp.append('\n');
}
tmp.append("</OpenContextPolicies>");
return tmp.toString();
}
synchronized ContextPolicy getContextPolicy(String contextID)
throws PolicyContextException
{
ContextPolicy policy = (ContextPolicy) openPolicies.get(contextID);
if (policy == null)
throw new PolicyContextException("No ContextPolicy exists for contextID=" + contextID);
return policy;
}
synchronized void initPolicyConfiguration(String contextID, boolean remove)
throws PolicyContextException
{
ContextPolicy policy = (ContextPolicy) activePolicies.remove(contextID);
if( policy == null )
policy = (ContextPolicy) openPolicies.get(contextID);
if (policy == null)
{
policy = new ContextPolicy(contextID);
}
openPolicies.put(contextID, policy);
if (remove == true)
policy.clear();
}
void addToExcludedPolicy(String contextID, Permission permission)
throws PolicyContextException
{
ContextPolicy policy = getContextPolicy(contextID);
policy.addToExcludedPolicy(permission);
}
void addToExcludedPolicy(String contextID, PermissionCollection permissions)
throws PolicyContextException
{
ContextPolicy policy = getContextPolicy(contextID);
policy.addToExcludedPolicy(permissions);
}
void addToRole(String contextID, String roleName, Permission permission)
throws PolicyContextException
{
ContextPolicy policy = getContextPolicy(contextID);
policy.addToRole(roleName, permission);
}
void addToRole(String contextID, String roleName, PermissionCollection permissions)
throws PolicyContextException
{
ContextPolicy policy = getContextPolicy(contextID);
policy.addToRole(roleName, permissions);
}
void addToUncheckedPolicy(String contextID, Permission permission)
throws PolicyContextException
{
ContextPolicy policy = getContextPolicy(contextID);
policy.addToUncheckedPolicy(permission);
}
void addToUncheckedPolicy(String contextID, PermissionCollection permissions)
throws PolicyContextException
{
ContextPolicy policy = getContextPolicy(contextID);
policy.addToUncheckedPolicy(permissions);
}
void linkConfiguration(String contextID, PolicyConfiguration link)
throws PolicyContextException
{
ContextPolicy policy = getContextPolicy(contextID);
ContextPolicy linkPolicy = getContextPolicy(link.getContextID());
policy.linkConfiguration(linkPolicy);
}
public void commit(String contextID)
throws PolicyContextException
{
ContextPolicy policy = getContextPolicy(contextID);
openPolicies.remove(contextID);
activePolicies.put(contextID, policy);
policy.commit();
}
public void delete(String contextID)
throws PolicyContextException
{
ContextPolicy policy = (ContextPolicy) activePolicies.remove(contextID);
if( policy == null )
policy = (ContextPolicy) openPolicies.remove(contextID);
if( policy != null )
policy.delete();
}
void removeExcludedPolicy(String contextID)
throws PolicyContextException
{
ContextPolicy policy = getContextPolicy(contextID);
policy.removeExcludedPolicy();
}
void removeRole(String contextID, String roleName)
throws PolicyContextException
{
ContextPolicy policy = getContextPolicy(contextID);
policy.removeRole(roleName);
}
void removeUncheckedPolicy(String contextID)
throws PolicyContextException
{
ContextPolicy policy = getContextPolicy(contextID);
policy.removeUncheckedPolicy();
}
private static class PolicyProxy extends Policy
{
private Policy delegate;
PolicyProxy(Policy delegate)
{
this.delegate = delegate;
}
public void refresh()
{
delegate.refresh();
}
public PermissionCollection getPermissions(CodeSource codesource)
{
return delegate.getPermissions(codesource);
}
public boolean implies(ProtectionDomain domain, Permission permission)
{
return delegate.implies(domain, permission);
}
public PermissionCollection getPermissions(ProtectionDomain domain)
{
return delegate.getPermissions(domain);
}
}
}