Back to index

nordugrid-arc-nox  1.1.0~rc6
GACLPDP.cpp
Go to the documentation of this file.
00001 #ifdef HAVE_CONFIG_H
00002 #include <config.h>
00003 #endif
00004 
00005 #include <arc/security/ArcPDP/Evaluator.h>
00006 #include <arc/security/ArcPDP/EvaluatorLoader.h>
00007 /*
00008 #include <iostream>
00009 #include <fstream>
00010 
00011 #include <arc/loader/PDPLoader.h>
00012 #include <arc/XMLNode.h>
00013 #include <arc/Thread.h>
00014 #include <arc/ArcConfig.h>
00015 #include <arc/ArcLocation.h>
00016 #include <arc/Logger.h>
00017 #include <arc/security/ArcPDP/Response.h>
00018 #include <arc/security/ArcPDP/attr/AttributeValue.h>
00019 #include <arc/security/ArcPDP/EvaluatorLoader.h>
00020 */
00021 
00022 #include "GACLPDP.h"
00023 
00024 Arc::Logger ArcSec::GACLPDP::logger(ArcSec::PDP::logger,"GACLPDP");
00025 
00026 Arc::SecAttrFormat ArcSec::GACLPDP::GACL("gacl");
00027 
00028 /*
00029 static ArcSec::PDP* get_pdp(Arc::Config *cfg,Arc::ChainContext *ctx) {
00030     return new ArcSec::ArcPDP(cfg);
00031 }
00032 
00033 pdp_descriptors ARC_PDP_LOADER = {
00034     { "gacl.pdp", 0, &get_pdp},
00035     { NULL, 0, NULL }
00036 };
00037 */
00038 
00039 using namespace Arc;
00040 
00041 namespace ArcSec {
00042 
00043 Plugin* GACLPDP::get_gacl_pdp(PluginArgument* arg) {
00044     PDPPluginArgument* pdparg =
00045             arg?dynamic_cast<PDPPluginArgument*>(arg):NULL;
00046     if(!pdparg) return NULL;
00047     return new GACLPDP((Config*)(*pdparg));
00048 }
00049 
00050 class GACLPDPContext:public Arc::MessageContextElement {
00051  friend class GACLPDP;
00052  private:
00053   Evaluator* eval;
00054  public:
00055   GACLPDPContext(Evaluator* e);
00056   GACLPDPContext(void);
00057   virtual ~GACLPDPContext(void);
00058 };
00059 
00060 GACLPDPContext::~GACLPDPContext(void) {
00061   if(eval) delete eval;
00062 }
00063 
00064 GACLPDPContext::GACLPDPContext(Evaluator* e):eval(e) {
00065 }
00066 
00067 GACLPDPContext::GACLPDPContext(void):eval(NULL) {
00068   EvaluatorLoader eval_loader;
00069   eval = eval_loader.getEvaluator(std::string("gacl.evaluator"));
00070 }
00071 
00072 GACLPDP::GACLPDP(Config* cfg):PDP(cfg) {
00073   XMLNode pdp_node(*cfg);
00074 
00075   XMLNode filter = (*cfg)["Filter"];
00076   if((bool)filter) {
00077     XMLNode select_attr = filter["Select"];
00078     XMLNode reject_attr = filter["Reject"];
00079     for(;(bool)select_attr;++select_attr) select_attrs.push_back((std::string)select_attr);
00080     for(;(bool)reject_attr;++reject_attr) reject_attrs.push_back((std::string)reject_attr);
00081   };
00082   XMLNode policy_store = (*cfg)["PolicyStore"];
00083   XMLNode policy_location = policy_store["Location"];
00084   for(;(bool)policy_location;++policy_location) policy_locations.push_back((std::string)policy_location);
00085   XMLNode policy_doc = policy_store["Policy"];
00086   for(;(bool)policy_doc;++policy_doc) policy_docs.AddNew(policy_doc);
00087 }
00088 
00089 bool GACLPDP::isPermitted(Message *msg) const{
00090   Evaluator* eval = NULL;
00091 
00092   std::string ctxid = "arcsec.gaclpdp";
00093   try {
00094     Arc::MessageContextElement* mctx = (*(msg->Context()))[ctxid];
00095     if(mctx) {
00096       GACLPDPContext* pdpctx = dynamic_cast<GACLPDPContext*>(mctx);
00097       if(pdpctx) {
00098         eval=pdpctx->eval;
00099       };
00100     };
00101   } catch(std::exception& e) { };
00102   if(!eval) {
00103     GACLPDPContext* pdpctx = new GACLPDPContext();
00104     if(pdpctx) {
00105       eval=pdpctx->eval;
00106       if(eval) {
00107         for(std::list<std::string>::const_iterator it = policy_locations.begin(); it!= policy_locations.end(); it++) {
00108           eval->addPolicy(SourceFile(*it));
00109         }
00110         for(int n = 0;n<policy_docs.Size();++n) {
00111           eval->addPolicy(Source(const_cast<Arc::XMLNodeContainer&>(policy_docs)[n]));
00112         }
00113         msg->Context()->Add(ctxid, pdpctx);
00114       } else {
00115         delete pdpctx;
00116       }
00117     }
00118     if(!eval) logger.msg(ERROR, "Can not dynamically produce Evaluator");
00119   }
00120   if(!eval) {
00121     logger.msg(ERROR,"Evaluator for GACLPDP was not loaded"); 
00122     return false;
00123   };
00124 
00125   MessageAuth* mauth = msg->Auth()->Filter(select_attrs,reject_attrs);
00126   MessageAuth* cauth = msg->AuthContext()->Filter(select_attrs,reject_attrs);
00127   if((!mauth) && (!cauth)) {
00128     logger.msg(ERROR,"Missing security object in message");
00129     return false;
00130   };
00131   NS ns;
00132   XMLNode requestxml(ns,"");
00133   if(mauth) {
00134     if(!mauth->Export(GACL,requestxml)) {
00135       delete mauth;
00136       logger.msg(ERROR,"Failed to convert security information to ARC request");
00137       return false;
00138     };
00139     delete mauth;
00140   };
00141   if(cauth) {
00142     if(!cauth->Export(GACL,requestxml)) {
00143       delete mauth;
00144       logger.msg(ERROR,"Failed to convert security information to ARC request");
00145       return false;
00146     };
00147     delete cauth;
00148   };
00149   if(DEBUG >= logger.getThreshold()) {
00150     std::string s;
00151     requestxml.GetXML(s);
00152     logger.msg(DEBUG,"GACL Auth. request: %s",s);
00153   };
00154   if(requestxml.Size() <= 0) {
00155     logger.msg(ERROR,"No requested security information was collected");
00156     return false;
00157   };
00158 
00159   //Call the evaluation functionality inside Evaluator
00160   Response *resp = eval->evaluate(requestxml);
00161   if(!resp) return false;
00162   ResponseList rlist = resp->getResponseItems();
00163   int size = rlist.size();
00164 
00165   // Current implementation of GACL Evaluator returns only one item
00166   // and only PERMIT/DENY results.
00167   if(rlist.size() <= 0) { delete resp; return false; };
00168   ResponseItem* item = rlist[0];
00169   if(item->res != DECISION_PERMIT) { delete resp; return false; };
00170   delete resp;
00171   return true;
00172 }
00173 
00174 GACLPDP::~GACLPDP(){
00175 }
00176 
00177 } // namespace ArcSec
00178