Back to index

nordugrid-arc-nox  1.1.0~rc6
XACMLPDP.cpp
Go to the documentation of this file.
00001 #ifdef HAVE_CONFIG_H
00002 #include <config.h>
00003 #endif
00004 
00005 #include <iostream>
00006 #include <fstream>
00007 
00008 #include <arc/XMLNode.h>
00009 #include <arc/Thread.h>
00010 #include <arc/ArcConfig.h>
00011 #include <arc/ArcLocation.h>
00012 #include <arc/Logger.h>
00013 #include <arc/security/ArcPDP/Response.h>
00014 #include <arc/security/ArcPDP/attr/AttributeValue.h>
00015 #include <arc/security/ArcPDP/EvaluatorLoader.h>
00016 
00017 #include "XACMLPDP.h"
00018 
00019 Arc::Logger ArcSec::XACMLPDP::logger(ArcSec::PDP::logger,"XACMLPDP");
00020 
00021 using namespace Arc;
00022 
00023 namespace ArcSec {
00024 
00025 Plugin* XACMLPDP::get_xacml_pdp(PluginArgument* arg) {
00026     ArcSec::PDPPluginArgument* pdparg =
00027             arg?dynamic_cast<ArcSec::PDPPluginArgument*>(arg):NULL;
00028     if(!pdparg) return NULL;
00029     return new XACMLPDP((Arc::Config*)(*pdparg));
00030 }
00031 
00032 // This class is used to store Evaluator per connection
00033 class XACMLPDPContext:public Arc::MessageContextElement {
00034  friend class XACMLPDP;
00035  private:
00036   Evaluator* eval;
00037  public:
00038   XACMLPDPContext(Evaluator* e);
00039   XACMLPDPContext(void);
00040   virtual ~XACMLPDPContext(void);
00041 };
00042 
00043 XACMLPDPContext::~XACMLPDPContext(void) {
00044   if(eval) delete eval;
00045 }
00046 
00047 XACMLPDPContext::XACMLPDPContext(Evaluator* e):eval(e) {
00048 }
00049 
00050 XACMLPDPContext::XACMLPDPContext(void):eval(NULL) {
00051   std::string evaluator = "xacml.evaluator"; 
00052   EvaluatorLoader eval_loader;
00053   eval = eval_loader.getEvaluator(evaluator);
00054 }
00055 
00056 XACMLPDP::XACMLPDP(Config* cfg):PDP(cfg) /*, eval(NULL)*/ {
00057   XMLNode pdp_node(*cfg);
00058 
00059   XMLNode filter = (*cfg)["Filter"];
00060   if((bool)filter) {
00061     XMLNode select_attr = filter["Select"];
00062     XMLNode reject_attr = filter["Reject"];
00063     for(;(bool)select_attr;++select_attr) select_attrs.push_back((std::string)select_attr);
00064     for(;(bool)reject_attr;++reject_attr) reject_attrs.push_back((std::string)reject_attr);
00065   };
00066   XMLNode policy_store = (*cfg)["PolicyStore"];
00067   XMLNode policy_location = policy_store["Location"];
00068   for(;(bool)policy_location;++policy_location) policy_locations.push_back((std::string)policy_location);
00069   XMLNode policy = (*cfg)["Policy"];
00070   for(;(bool)policy;++policy) policies.AddNew(policy);
00071   policy_combining_alg = (std::string)((*cfg)["PolicyCombiningAlg"]);
00072 }
00073 
00074 bool XACMLPDP::isPermitted(Message *msg) const {
00075   //Compose Request based on the information inside message, the Request will be
00076   //compatible to xacml request schema
00077 
00078   Evaluator* eval = NULL;
00079 
00080   const std::string ctxid = "arcsec.xacmlpdp";
00081   try {
00082     Arc::MessageContextElement* mctx = (*(msg->Context()))[ctxid];
00083     if(mctx) {
00084       XACMLPDPContext* pdpctx = dynamic_cast<XACMLPDPContext*>(mctx);
00085       if(pdpctx) {
00086         eval=pdpctx->eval;
00087       }
00088       else { logger.msg(INFO, "Can not find XACMLPDPContext"); }
00089     };
00090   } catch(std::exception& e) { };
00091   if(!eval) {
00092     XACMLPDPContext* pdpctx = new XACMLPDPContext();
00093     if(pdpctx) {
00094       eval=pdpctx->eval;
00095       if(eval) {
00096         //for(Arc::AttributeIterator it = (msg->Attributes())->getAll("PDP:POLICYLOCATION"); it.hasMore(); it++) {
00097         //  eval->addPolicy(SourceFile(*it));
00098         //}
00099         for(std::list<std::string>::const_iterator it = policy_locations.begin(); it!= policy_locations.end(); it++) {
00100           eval->addPolicy(SourceFile(*it));
00101         }
00102         for(int n = 0;n<policies.Size();++n) {
00103           eval->addPolicy(Source(const_cast<Arc::XMLNodeContainer&>(policies)[n]));
00104         }
00105         if(!policy_combining_alg.empty()) {
00106           if(policy_combining_alg == "EvaluatorFailsOnDeny") {
00107             eval->setCombiningAlg(EvaluatorFailsOnDeny);
00108           } else if(policy_combining_alg == "EvaluatorStopsOnDeny") {
00109             eval->setCombiningAlg(EvaluatorStopsOnDeny);
00110           } else if(policy_combining_alg == "EvaluatorStopsOnPermit") {
00111             eval->setCombiningAlg(EvaluatorStopsOnPermit);
00112           } else if(policy_combining_alg == "EvaluatorStopsNever") {
00113             eval->setCombiningAlg(EvaluatorStopsNever);
00114           } else {
00115             AlgFactory* factory = eval->getAlgFactory();
00116             if(!factory) {
00117               logger.msg(WARNING, "Evaluator does not support loadable Combining Algorithms");
00118             } else {
00119               CombiningAlg* algorithm = factory->createAlg(policy_combining_alg);
00120               if(!algorithm) {
00121                 logger.msg(ERROR, "Evaluator does not support specified Combining Algorithm - %s",policy_combining_alg);
00122               } else {
00123                 eval->setCombiningAlg(algorithm);
00124               };
00125             };
00126           };
00127         };
00128         msg->Context()->Add(ctxid, pdpctx);
00129       } else {
00130         delete pdpctx;
00131       }
00132     }
00133     if(!eval) logger.msg(ERROR, "Can not dynamically produce Evaluator");
00134   }
00135   if(!eval) {
00136     logger.msg(ERROR,"Evaluator for XACMLPDP was not loaded"); 
00137     return false;
00138   };
00139 
00140   MessageAuth* mauth = msg->Auth()->Filter(select_attrs,reject_attrs);
00141   MessageAuth* cauth = msg->AuthContext()->Filter(select_attrs,reject_attrs);
00142   if((!mauth) && (!cauth)) {
00143     logger.msg(ERROR,"Missing security object in message");
00144     return false;
00145   };
00146   NS ns;
00147   XMLNode requestxml(ns,"");
00148   if(mauth) {
00149     if(!mauth->Export(SecAttr::XACML,requestxml)) {
00150       delete mauth;
00151       logger.msg(ERROR,"Failed to convert security information to XACML request");
00152       return false;
00153     };
00154     delete mauth;
00155   };
00156   if(cauth) {
00157     if(!cauth->Export(SecAttr::XACML,requestxml)) {
00158       delete mauth;
00159       logger.msg(ERROR,"Failed to convert security information to XACML request");
00160       return false;
00161     };
00162     delete cauth;
00163   };
00164   {
00165     std::string s;
00166     requestxml.GetXML(s);
00167     logger.msg(DEBUG,"XACML request: %s",s);
00168   };
00169   if(requestxml.Size() <= 0) {
00170     logger.msg(ERROR,"No requested security information was collected");
00171     return false;
00172   };
00173 
00174   //Call the evaluation functionality inside Evaluator
00175   Response *resp = eval->evaluate(requestxml);
00176   ArcSec::ResponseList rlist = resp->getResponseItems();
00177   std::cout<<rlist[0]->res<<std::endl;
00178   bool result = false;
00179   if(rlist[0]->res == DECISION_PERMIT) { logger.msg(INFO, "Authorized from xacml.pdp"); result = true; }
00180   else logger.msg(ERROR, "UnAuthorized from xacml.pdp");
00181   
00182   if(resp) delete resp;
00183     
00184   return result;
00185 }
00186 
00187 XACMLPDP::~XACMLPDP(){
00188 }
00189 
00190 } // namespace ArcSec
00191