Back to index

nordugrid-arc-nox  1.1.0~rc6
XACMLPolicy.cpp
Go to the documentation of this file.
00001 #ifdef HAVE_CONFIG_H
00002 #include <config.h>
00003 #endif
00004 
00005 #include <list>
00006 
00007 #include "XACMLPolicy.h"
00008 #include "XACMLRule.h"
00009 
00010 Arc::Logger ArcSec::XACMLPolicy::logger(Arc::Logger::rootLogger, "XACMLPolicy");
00011 
00012 static Arc::NS policyns("policy", "urn:oasis:names:tc:xacml:2.0:policy:schema:os");
00013 
00016 Arc::Plugin* ArcSec::XACMLPolicy::get_policy(Arc::PluginArgument* arg) {
00017     //std::cout<<"Argument type of XACMLPolicy:"<<typeid(arg).name()<<std::endl;
00018     if(arg==NULL) return NULL;
00019     Arc::ClassLoaderPluginArgument* clarg =
00020             arg?dynamic_cast<Arc::ClassLoaderPluginArgument*>(arg):NULL;
00021     if(!clarg) return NULL;
00022     // Check if empty or valid policy is supplied
00023     Arc::XMLNode* doc = (Arc::XMLNode*)(*clarg);
00024     if(doc==NULL) {
00025         std::cerr<<"XACMLPolicy creation requires XMLNode as argument"<<std::endl;
00026         return NULL;
00027     }
00028     //if(!(*doc)) return new ArcSec::XACMLPolicy;
00029     ArcSec::XACMLPolicy* policy = new ArcSec::XACMLPolicy(*doc);
00030     if((!policy) || (!(*policy))) {
00031       delete policy;
00032       return NULL;
00033     };
00034     return policy;
00035 }
00036 
00037 using namespace Arc;
00038 using namespace ArcSec;
00039 
00040 XACMLPolicy::XACMLPolicy(void) : Policy(), comalg(NULL) {
00041   Arc::XMLNode newpolicy(policyns,"policy:Policy");
00042   newpolicy.New(policynode);
00043   policytop=policynode;
00044 }
00045 
00046 XACMLPolicy::XACMLPolicy(const XMLNode node) : Policy(node), comalg(NULL), target(NULL) {
00047   if((!node) || (node.Size() == 0)) {
00048     logger.msg(ERROR,"Policy is empty");
00049     return;
00050   }
00051   node.New(policynode);
00052 
00053   std::list<XMLNode> res = policynode.XPathLookup("//policy:Policy",policyns);
00054   if(res.empty()) {
00055     logger.msg(ERROR,"Can not find <Policy/> element with proper namespace");
00056     policynode.Destroy();
00057     return;
00058   }
00059   policytop = *(res.begin());
00060 }
00061 
00062 XACMLPolicy::XACMLPolicy(const XMLNode node, EvaluatorContext* ctx) : Policy(node), comalg(NULL), target(NULL) {
00063   if((!node) || (node.Size() == 0)) {
00064     logger.msg(ERROR,"Policy is empty");
00065     return;
00066   }
00067   node.New(policynode);
00068   std::list<XMLNode> res = policynode.XPathLookup("//policy:Policy",policyns);
00069   if(res.empty()) {
00070     policynode.Destroy();
00071     return;
00072   }
00073   policytop = *(res.begin());
00074   setEvaluatorContext(ctx);
00075   make_policy();
00076 }
00077 
00078 void XACMLPolicy::make_policy() {
00079   //EvalResult.node record the policy(in XMLNode) information about evaluation result.
00080   //According to the developer's requirement, 
00081   //EvalResult.node can include rules(in XMLNode) that "Permit" or "Deny" 
00082   //the request tuple. In the existing code, it include all 
00083   //the original rules.
00084 
00085   if(!policynode) return;
00086   if(!policytop) return;
00087 
00088   evalres.node = policynode;
00089   evalres.effect = "Not_applicable";
00090 
00091   XACMLRule *rule;
00092   //Get AlgFactory from EvaluatorContext
00093   algfactory = (AlgFactory*)(*evaluatorctx); 
00094 
00095   XMLNode nd = policytop;
00096   XMLNode rnd;
00097   if((bool)nd){
00098     nd = policytop;
00099     id = (std::string)(nd.Attribute("PolicyId"));
00100 
00101     //Setup the rules' combining algorithm inside one policy, according to the "RuleCombiningAlgId" name
00102     if(nd.Attribute("RuleCombiningAlgId")) {
00103       std::string tmpstr = (std::string)(nd.Attribute("RuleCombiningAlgId"));
00104       size_t found = tmpstr.find_last_of(":");
00105       std::string algstr = tmpstr.substr(found+1);
00106       if(algstr == "deny-overrides") algstr = "Deny-Overrides";
00107       else if(algstr == "permit-overrides") algstr = "Permit-Overrides";
00108       comalg = algfactory->createAlg(algstr);
00109     }
00110     else comalg = algfactory->createAlg("Deny-Overrides");
00111     
00112     description = (std::string)(nd["Description"]);  
00113   }
00114   
00115   logger.msg(INFO, "PolicyId: %s  Alg inside this policy is:-- %s", id, comalg?(comalg->getalgId()):"");
00116 
00117   XMLNode targetnode = nd["Target"];
00118   if(((bool)targetnode) && ((bool)(targetnode.Child()))) 
00119     target = new XACMLTarget(targetnode, evaluatorctx);
00120 
00121   for ( int i=0;; i++ ){
00122     rnd = nd["Rule"][i];
00123     if(!rnd) break;
00124     rule = new XACMLRule(rnd, evaluatorctx);
00125     subelements.push_back(rule);
00126   }
00127 }
00128 
00129 MatchResult XACMLPolicy::match(EvaluationCtx* ctx){
00130   MatchResult res;
00131   if(target != NULL) res = target->match(ctx);
00132   else { logger.msg(Arc::INFO, "No target available inside the policy"); res = INDETERMINATE; }
00133   return res;
00134 }
00135 
00136 Result XACMLPolicy::eval(EvaluationCtx* ctx){
00137   Result result = DECISION_NOT_APPLICABLE;
00138   if(target != NULL) {
00139     MatchResult matchres = target->match(ctx);
00140     if(matchres == NO_MATCH)  return result;
00141     else if(matchres == INDETERMINATE) {result = DECISION_INDETERMINATE; return result;}
00142   }
00143  
00144   result = comalg?comalg->combine(ctx, subelements):DECISION_INDETERMINATE;
00145   if(result == DECISION_PERMIT) evalres.effect = "Permit";
00146   else if(result == DECISION_DENY) evalres.effect = "Deny";
00147   else if(result == DECISION_INDETERMINATE) evalres.effect = "Indeterminate";
00148 
00149   return result;
00150 }
00151 
00152 EvalResult& XACMLPolicy::getEvalResult(){
00153   return evalres;
00154 }
00155 
00156 XACMLPolicy::~XACMLPolicy(){
00157   while(!(subelements.empty())){
00158     delete subelements.back();
00159     subelements.pop_back();
00160   }
00161   if(target != NULL) delete target;
00162 }