Back to index

nordugrid-arc-nox  1.1.0~rc6
XACMLApply.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 <arc/security/ArcPDP/attr/AttributeValue.h>
00008 
00009 #include "XACMLPolicy.h"
00010 #include "XACMLRule.h"
00011 #include "XACMLApply.h"
00012 
00013 static Arc::Logger logger(Arc::Logger::rootLogger, "XACMLApply");
00014 
00015 using namespace Arc;
00016 using namespace ArcSec;
00017 
00018 XACMLApply::XACMLApply(XMLNode& node, EvaluatorContext* ctx) : applynode(node), function(NULL) {
00019   attrfactory = (AttributeFactory*)(*ctx);
00020   fnfactory = (FnFactory*)(*ctx); 
00021 
00022   functionId = (std::string)(node.Attribute("FunctionId"));
00023   //get the suffix of xacml-formated FunctionId, like
00024   //"urn:oasis:names:tc:xacml:1.0:function:and",
00025   //and use it as the function name
00026   std::size_t found = functionId.find_last_of(":");
00027   std::string funcname = functionId.substr(found+1);
00028 
00029   if(funcname.empty()) { logger.msg(ERROR, "Can not create function: FunctionId does not exist"); return; }; 
00030   
00031   //create the Function based on the function name
00032   function = fnfactory->createFn(funcname);
00033   if(!function) { logger.msg(ERROR, "Can not create function %s", funcname); return; }
00034 
00035   //create the AttributeValue, AttributeDesignator and AttributeSelector
00036   XMLNode cnd;
00037 
00038   XMLNode attrval_nd;
00039   std::string attrval_id;
00040   std::string attrval_type;
00041   for(int i = 0;;i++ ) {
00042     cnd = node.Child(i);
00043     if(!cnd) break;
00044     std::string name = cnd.Name();
00045     if(name.find("AttributeValue") != std::string::npos) {
00046       std::string data_type = cnd.Attribute("DataType");
00047       //<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">
00048       //  http://www.med.example.com/schemas/record.xsd
00049       //</AttributeValue>
00050       attrval_nd = cnd;
00051       std::size_t f = data_type.find_last_of("#"); //http://www.w3.org/2001/XMLSchema#string
00052       if(f!=std::string::npos) {
00053         attrval_type = data_type.substr(f+1);
00054       }
00055       else {
00056         f=data_type.find_last_of(":"); //urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name
00057         attrval_type = data_type.substr(f+1);
00058       }
00059       AttributeValue* attrval = attrfactory->createValue(attrval_nd, attrval_type);
00060       attrval_list[i] = attrval;
00061     }
00062     else if(name.find("AttributeSelector") != std::string::npos) {
00063       AttributeSelector* selector = new AttributeSelector(cnd, attrfactory);
00064       selector_list[i] = selector;
00065     }
00066     else if(name.find("AttributeDesignator") != std::string::npos) {
00067       AttributeDesignator* designator = new AttributeDesignator(cnd, attrfactory);
00068       designator_list[i] = designator;
00069     }
00070     else if(name == "Apply") {
00071       XACMLApply* apply = new XACMLApply(cnd, ctx);
00072       sub_apply_list[i] = apply;
00073     }
00074   }
00075 }
00076 
00077 XACMLApply::~XACMLApply() {
00078   std::map<int, AttributeValue*>::iterator attrval_it;
00079   std::map<int, AttributeSelector*>::iterator selector_it;
00080   std::map<int, AttributeDesignator*>::iterator designator_it;
00081   std::map<int, XACMLApply*>::iterator apply_it;
00082   attrval_it = attrval_list.begin();
00083   selector_it = selector_list.begin();
00084   designator_it = designator_list.begin();
00085   apply_it = sub_apply_list.begin();
00086  
00087   for(;attrval_it != attrval_list.end(); attrval_it++) { 
00088     AttributeValue* attrval = (*attrval_it).second;
00089     attrval_list.erase(attrval_it);
00090     delete attrval;
00091   }
00092   for(;selector_it != selector_list.end(); selector_it++) {  
00093     AttributeSelector* selector = (*selector_it).second;
00094     selector_list.erase(selector_it);
00095     delete selector;
00096   }
00097   for(;designator_it != designator_list.end(); designator_it++) {
00098     AttributeDesignator* designator = (*designator_it).second;
00099     designator_list.erase(designator_it);
00100     delete designator;
00101   }
00102   for(;apply_it != sub_apply_list.end(); apply_it++) {
00103     XACMLApply* apply = (*apply_it).second;
00104     sub_apply_list.erase(apply_it);
00105     delete apply;
00106   }
00107 }
00108 
00109 std::list<AttributeValue*> XACMLApply::evaluate(EvaluationCtx* ctx) {
00110   std::list<AttributeValue*> list;
00111   std::list<AttributeValue*> attrlist;
00112   std::list<AttributeValue*> attrlist_to_remove;
00113 
00114   AttributeValue* attrval = NULL;
00115   AttributeSelector* selector = NULL;
00116   AttributeDesignator* designator = NULL;
00117   XACMLApply* apply = NULL;
00118   std::map<int, AttributeValue*>::iterator attrval_it;
00119   std::map<int, AttributeSelector*>::iterator selector_it;
00120   std::map<int, AttributeDesignator*>::iterator designator_it;
00121   std::map<int, XACMLApply*>::iterator apply_it;
00122   for(int i=0;;i++) {
00123     attrval_it = attrval_list.find(i);
00124     selector_it = selector_list.find(i);
00125     designator_it = designator_list.find(i);
00126     apply_it = sub_apply_list.find(i);
00127 
00128     if((attrval_it == attrval_list.end()) &&
00129        (selector_it == selector_list.end()) && 
00130        (designator_it == designator_list.end()) &&
00131        (apply_it == sub_apply_list.end()))
00132       break;
00133 
00134     if(attrval_it != attrval_list.end()) {
00135       attrlist.push_back((*attrval_it).second);
00136     }
00137     if(selector_it != selector_list.end()) {
00138       list = (*selector_it).second->evaluate(ctx);
00139       attrlist.insert(attrlist.end(), list.begin(), list.end());
00140       attrlist_to_remove.insert(attrlist_to_remove.end(), list.begin(), list.end());
00141     }
00142     if(designator_it != designator_list.end()) {
00143       list = (*designator_it).second->evaluate(ctx);
00144       attrlist.insert(attrlist.end(), list.begin(), list.end());
00145       attrlist_to_remove.insert(attrlist_to_remove.end(), list.begin(), list.end());
00146     }
00147     if(apply_it != sub_apply_list.end()) {
00148       list = (*apply_it).second->evaluate(ctx);
00149       attrlist.insert(attrlist.end(), list.begin(), list.end());
00150       attrlist_to_remove.insert(attrlist_to_remove.end(), list.begin(), list.end());
00151     }
00152   }
00153 
00154   //Evaluate
00155   std::list<AttributeValue*> res;
00156   try{
00157     std::cout<<"There are "<<attrlist.size()<<" attribute values to be evaluated"<<std::endl;
00158     res = function->evaluate(attrlist, false);
00159   } catch(std::exception&) { };
00160 
00161   while(!(attrlist_to_remove.empty())) {
00162     //Note that the attributes which are directly parsed 
00163     //from policy should not be deleted here.
00164     //Instead, they should be deleted by deconstructor of XACMLApply
00165     AttributeValue* val = attrlist_to_remove.back();
00166     attrlist_to_remove.pop_back();
00167     delete val;
00168   }
00169 
00170   return res;
00171 }
00172