package com.nailabs.abac.process;
import com.nailabs.abac.test.Debug;
import com.nailabs.abac.credential.RtmlFrontier;
import edu.stanford.peer.rbtm.credential.*;
import edu.stanford.peer.rbtm.engine.*;
import edu.stanford.peer.rbtm.test.*;
import edu.stanford.peer.rbtm.util.*;
import java.util.*;
/**
* A manager class for frontier functions. Each set of functions should
* be unique to a principal. The manager is a singleton object with a method
* for obtaining a set of specific frontiers.
*/
public class FrontierManager extends com.nailabs.abac.test.TestEngine
implements java.io.Serializable {
/** Singleton reference table for sharing frontiers. */
static Hashtable frontiers = new Hashtable(5);
/** The principal identifier, which is an Entity name */
protected Entity self;
/**
* The configuration hashmap. Section name is key and stringified
* line vectors are the values
*/
protected HashMap conf;
/** The set of issuer traceable credentials */
protected HashSet cSuperI = new HashSet();
/** The set of subject traceable credentials */
protected HashSet cSuperS = new HashSet();
/** The set of subject traceable roles */
protected HashSet subjectTraces = new HashSet();
protected HashSet issuerTracesDef = new HashSet();
protected HashSet issuerTracesAll = new HashSet();
/** a search engine which uses the oppo()
predicate */
protected GraphEngine oppoLocal;
/** a search engine which uses the oppo()
predicate */
protected GraphEngine oppoFrontier;
/** a search engine which uses the sens()
predicate */
protected GraphEngine sensFrontier;
/** a search engine which uses the simp()
predicate */
protected GraphEngine simpFrontier;
/** the acknowledgement policy for this principal entity */
protected AckPolicy ackPolicy;
/** the access control policy for this principal entity */
protected ACPolicy acPolicy;
/** constructor for subclasses */
protected FrontierManager() { }
/** default constructor, only used internally */
protected FrontierManager(HashMap config) {
init(config);
}
/**
* initialization is no longer in constructor, so subclasses can
* manipulate the configuration hash map.
*/
protected void init(HashMap config) {
//int track = TRACK_ALL;
// (0) get the configurations entity identifier
this.self =(Entity) config.get("EntityID");
// (1) load acknowledgement(ACK) policy
ackPolicy = (AckPolicy)config.get("AckPolicy");
// (2) load access control (AC) policy
acPolicy = (ACPolicy)config.get("AccessControl");
// (3) load issuer traceable roles
issuerTracesAll = (HashSet)config.get("IssuerTracesAll");
issuerTracesDef = (HashSet)config.get("IssuerTracesDef");
// (4) load subject traceale roles
subjectTraces = (HashSet)config.get("SubjectTraceable");
// (5) construct sensitive roles predicate from the ack policy
Sens sens = new Sens(ackPolicy.getSensitiveRoles());
// (6) construct opponent predicate from the issuer traceable roles
Oppo oppo = new Oppo(new Vector(issuerTracesDef));
oppo.addSubjects(new Vector(issuerTracesAll));
// (7) construct the frontier functions with their predicates
oppoLocal = new GraphEngine();
//System.out.println("------> Sensitive Graph");
sensFrontier = new GraphEngine(sens);
//System.out.println("------> Opponent Graph");
oppoFrontier = new GraphEngine(oppo);
//System.out.println("------> Simple Graph");
simpFrontier = new GraphEngine(new Simp());
// TBD: Does this really need to be separated into two mutually exclusive
// credential sets?
// (8) add policy reachable credentials
System.out.println("------> Policy Reachable");
HashSet policyReachable = (HashSet)config.get("PolicyReachable");
Iterator ci = policyReachable.iterator();
while(ci.hasNext()) {
addPolicyReachable((StaticCredential)ci.next());
}
// (9) add self reachable credentials
System.out.println("------> Self Traceable");
HashSet selfReachable = (HashSet)config.get("SelfReachable");
Iterator cs = selfReachable.iterator();
while(cs.hasNext()) {
addSelfReachable((StaticCredential)cs.next());
}
}
public static void addFrontier(HashMap config) {
Entity key = (Entity)config.get("EntityID");
boolean hasRTML = config.containsKey("RTML");
System.out.println("Begin Configuration for " + key);
if(frontiers.contains(key.toString()))
System.out.println("WARNING overwriting frontier manager for " +
key);
FrontierManager frontier = hasRTML? new RtmlFrontier(config):
new FrontierManager(config);
frontiers.put(key.toString(), frontier);
System.out.println("End Configuration for " + key);
}
/** public instance accessor method for a specific frontier set */
public static FrontierManager getFrontier(Entity self) {
System.out.println("self = " + self);
FrontierManager instance =
(FrontierManager)frontiers.get(self.toString());
return instance;
}
/** public accessor for a list of instance keys */
public static Set getFrontiers() { return frontiers.keySet(); }
/** the unique identifier for this set of frontier functions */
public Entity getSelf() { return self; }
/** Extract the role name from a role expression (e.g. r from ) */
protected RoleName getRoleName(StaticCredential cred) {
return getRoleName(cred.getDefinedRole());
}
/** Extract the role name from a role expression (e.g. r from A.r) */
protected RoleName getRoleName(EntityExpression expr) {
if(expr != null && (expr instanceof Role)) {
return ((Role)expr).getName();
}
return null;
}
/** adds an issuer traceable credential to the frontier set */
public void addSelfReachable(StaticCredential cred) {
if(isSubjectTraceable(getRoleName(cred))) {
sensFrontier.addCredential(cred);
simpFrontier.addCredential(cred);
cSuperS.add(cred);
}
}
/** extracts issuer traceable roles from the credntial */
public void addPolicyReachable(StaticCredential cred) {
if(isIssuerTraceable(getRoleName(cred))) {
oppoFrontier.addCredential(cred);
oppoLocal.addCredential(cred);
cSuperI.add(cred);
}
}
/** adds an issuer-traces-all role to this frontier set */
public void addIssuerTracesAll(RoleName role) {
issuerTracesAll.add(role);
}
/** adds an issuer-traces-def role to this frontier set */
public void addIssuerTracesDef(RoleName role) {
issuerTracesDef.add(role);
}
/** adds an subject traceable credential to the frontier set */
public void addSubjectTraceable(RoleName role) {
subjectTraces.add(role);
}
public ResultEvidenceMap getOppoLocal(EntityExpression expr) {
//a specialized backward search for the LinkTTNode
Debug.rbtmStart();
System.out.println("-------BEGIN-LOCAL-SEARCH------------");
ResultEvidenceMap map = oppoLocal.backwardSearch(expr);
System.out.println("-------END-LOCAL-SEARCH--------------");
Debug.rbtmStop();
return map;
}
/** gets the frontier of policy traceable roles */
public ResultEvidenceMap getOppoFrontier(EntityExpression expr) {
// retrieve solutions AND evidence here
Debug.rbtmStart();
System.out.println("-------BEGIN-OPPO-SEARCH------------");
ResultEvidenceMap map = oppoFrontier.backwardSearch(expr);
System.out.println("-------END-OPPO-SEARCH--------------");
Debug.rbtmStop();
return map;
}
/** gets the frontier of sensitive roles */
public ResultEvidenceMap getSensFrontier(EntityExpression expr) {
Debug.rbtmStart();
System.out.println("-------BEGIN-SENS-SEARCH------------");
System.out.println("searching for " + expr);
ResultEvidenceMap map = sensFrontier.backwardSearch(expr);
System.out.println("map = " + map);
System.out.println("--------END-SENS-SEARCH-------------");
System.out.flush();
Debug.rbtmStop();
return map;
}
/** get the frontier of non-role entity expressions */
public ResultEvidenceMap getSimpFrontier(EntityExpression expr) {
Debug.rbtmStart();
System.out.println("-------BEGIN-SIMP-SEARCH------------");
ResultEvidenceMap map = simpFrontier.backwardSearch(expr);
System.out.println("--------END-SIMP-SEARCH------------");
Debug.rbtmStop();
return map;
}
public HashSet getOppoChain(EntityExpression root, EntityExpression leaf) {
HashSet results = new HashSet();
try {
getOppoFrontier(root);
Debug.rbtmStart();
System.out.println("Getting oppo chain from " + root + " to " +
leaf);
results = oppoFrontier.getChain(root, leaf);
Debug.rbtmStop();
} catch(Exception ex) {
ex.printStackTrace();
}
Debug.rbtmStop();
return results;
}
public HashSet getSensChain(EntityExpression root, EntityExpression leaf) {
//if(!getSensFrontier(root).containsResult(leaf)) {
//return null;
//}
try {
getSensFrontier(root);
Debug.rbtmStart();
System.out.println("---------BEGIN-SENS-CHAIN----------");
System.out.println("Getting sens chain from " + root + " to " +
leaf);
HashSet results = sensFrontier.getChain(root, leaf);
System.out.println("results = " + results);
System.out.println("-----------END-SENS-CHAIN----------\n");
Debug.rbtmStop();
return results;
} catch(Exception ex) {
ex.printStackTrace();
}
System.out.println("-----------END-SENS-CHAIN----------\n");
Debug.rbtmStop();
return new HashSet();
}
public HashSet getSimpChain(EntityExpression root, EntityExpression leaf) {
System.out.println("Getting simp chain from " + root + " to " + leaf);
getSimpFrontier(root);
Debug.rbtmStart();
HashSet results = simpFrontier.getChain(root, leaf);
Debug.rbtmStop();
return results;
}
public Iterator getCredentialsDefiningRole(RoleName name) {
Iterator i;
int count = 0;
HashSet results = new HashSet();
Debug.rbtmStart();
System.out.println("Finding credential defining the role name: "+name);
i = oppoFrontier.findCredentialsDefiningRole(name);
while(i.hasNext()) {
results.add(i.next());
System.out.println("count = " + ++count);
}
i = sensFrontier.findCredentialsDefiningRole(name);
while(i.hasNext()) {
results.add(i.next());
System.out.println("count = " + ++count);
}
Debug.rbtmStop();
Debug.debug("process", "\nDefining creds = " + results);
return results.iterator();
}
/** accessor for finding credentials which define a specified role */
public Iterator getCredentialsDefiningRole(Role role) {
Iterator i;
int count = 0;
HashSet results = new HashSet();
Debug.rbtmStart();
System.out.println("Finding credential defining the role: <" +
role.getBase() + "." + role.getName() + ">" );
i = oppoFrontier.findCredentialsDefiningRole(role);
while(i.hasNext()) {
results.add(i.next());
System.out.println("count = " + ++count);
}
System.out.println("oppoFrontier = " + oppoFrontier);
i = sensFrontier.findCredentialsDefiningRole(role);
while(i.hasNext()) {
results.add(i.next());
System.out.println("count = " + ++count);
}
Debug.debug("process", "\nDefining creds = " + results);
Debug.rbtmStop();
return results.iterator();
}
/** Is the specified credential policy traceable? */
public boolean isPolicyTraceable(StaticCredential cred) {
return cSuperI.contains(cred);
}
/** Can the specified credential be traced back to this negotiator? */
public boolean isSelfReachable(StaticCredential cred) {
return cSuperS.contains(cred);
}
public boolean isSubjectTraceable(RoleName role) {
return subjectTraces.contains(role);
}
public boolean isIssuerTracesDef(RoleName name) {
return (issuerTracesDef.contains(name));
}
public boolean isIssuerTracesAll(RoleName name) {
return (issuerTracesAll.contains(name));
}
public boolean isIssuerTraceable(RoleName role) {
return (issuerTracesAll.contains(role) || issuerTracesDef.contains(role));
}
public boolean isSensitive(EntityExpression expr) {
return sensFrontier.getPredicate().test(expr);
}
public boolean subjectTracesAll(RoleName name) {
return subjectTraces.contains(name);
}
public AckPolicy getAckPolicy() { return ackPolicy; }
public EntityExpression getAck(EntityExpression expr) {
return ackPolicy.requires(expr);
}
public ACPolicy getACPolicy() { return acPolicy; }
public EntityExpression getAC(Credential cred) {
if(acPolicy == null)return null;
return acPolicy.requires(cred);
}
protected void addSensitiveRole(Role name) {
Sens sens = (Sens)sensFrontier.getPredicate();
sens.addSensCred(name);
}
public String toString() {
StringBuffer buff = new StringBuffer("[FrontierManager self = ");
buff.append(self);
buff.append("\n sens = ").append(sensFrontier);
buff.append("\n\n oppo = ").append(oppoFrontier);
buff.append("\n\n simp = ").append(simpFrontier);
return buff.append("]").toString();
}
}