Back to index

nordugrid-arc-nox  1.1.0~rc6
EvaluatorLoader.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 <glibmm.h>
00007 #include <arc/XMLNode.h>
00008 #include <arc/ArcConfig.h>
00009 #include <arc/ArcLocation.h>
00010 #include <arc/Logger.h>
00011 #include <arc/security/ClassLoader.h>
00012 #include <arc/security/ArcPDP/Evaluator.h>
00013 
00014 #include "EvaluatorLoader.h"
00015 
00016 Arc::Logger ArcSec::EvaluatorLoader::logger(Arc::Logger::rootLogger, "EvaluatorLoader");
00017 
00018 namespace ArcSec {
00019   Arc::XMLNode arc_evaluator_cfg_nd("\
00020     <ArcConfig\
00021      xmlns=\"http://www.nordugrid.org/schemas/ArcConfig/2007\"\
00022      xmlns:pdp=\"http://www.nordugrid.org/schemas/pdp/Config\">\
00023      <ModuleManager>\
00024         <Path></Path>\
00025      </ModuleManager>\
00026      <Plugins Name='arcshc'>\
00027           <Plugin Name='__arc_attrfactory_modules__'>attrfactory</Plugin>\
00028           <Plugin Name='__arc_fnfactory_modules__'>fnfactory</Plugin>\
00029           <Plugin Name='__arc_algfactory_modules__'>algfactory</Plugin>\
00030           <Plugin Name='__arc_evaluator_modules__'>evaluator</Plugin>\
00031           <Plugin Name='__arc_request_modules__'>request</Plugin>\
00032           <Plugin Name='__arc_policy_modules__'>policy</Plugin>\
00033      </Plugins>\
00034      <pdp:PDPConfig>\
00035           <pdp:AttributeFactory name='arc.attrfactory' />\
00036           <pdp:CombingAlgorithmFactory name='arc.algfactory' />\
00037           <pdp:FunctionFactory name='arc.fnfactory' />\
00038           <pdp:Evaluator name='arc.evaluator' />\
00039           <pdp:Request name='arc.request' />\
00040           <pdp:Policy name='arc.policy' />\
00041      </pdp:PDPConfig>\
00042     </ArcConfig>");
00043 
00044   Arc::XMLNode xacml_evaluator_cfg_nd("\
00045     <ArcConfig\
00046      xmlns=\"http://www.nordugrid.org/schemas/ArcConfig/2007\"\
00047      xmlns:pdp=\"http://www.nordugrid.org/schemas/pdp/Config\">\
00048      <ModuleManager>\
00049         <Path></Path>\
00050      </ModuleManager>\
00051      <Plugins Name='arcshc'>\
00052           <Plugin Name='__arc_attrfactory_modules__'>attrfactory</Plugin>\
00053           <Plugin Name='__arc_fnfactory_modules__'>fnfactory</Plugin>\
00054           <Plugin Name='__arc_algfactory_modules__'>algfactory</Plugin>\
00055           <Plugin Name='__arc_evaluator_modules__'>evaluator</Plugin>\
00056           <Plugin Name='__arc_request_modules__'>request</Plugin>\
00057           <Plugin Name='__arc_policy_modules__'>policy</Plugin>\
00058      </Plugins>\
00059      <pdp:PDPConfig>\
00060           <pdp:AttributeFactory name='xacml.attrfactory' />\
00061           <pdp:CombingAlgorithmFactory name='xacml.algfactory' />\
00062           <pdp:FunctionFactory name='xacml.fnfactory' />\
00063           <pdp:Evaluator name='xacml.evaluator' />\
00064           <pdp:Request name='xacml.request' />\
00065           <pdp:Policy name='xacml.policy' />\
00066      </pdp:PDPConfig>\
00067     </ArcConfig>");
00068 
00069 EvaluatorLoader::EvaluatorLoader() {
00070   class_config_list_.push_back(arc_evaluator_cfg_nd);
00071   class_config_list_.push_back(xacml_evaluator_cfg_nd);
00072 }
00073 
00074 Evaluator* EvaluatorLoader::getEvaluator(const std::string& classname) {
00075   ArcSec::Evaluator* eval = NULL;
00076   Arc::ClassLoader* classloader = NULL;
00077 
00078   //Get the lib path from environment, and put it into the configuration xml node
00079   std::list<std::string> plugins = Arc::ArcLocation::GetPlugins();
00080 
00081   Arc::XMLNode node;
00082   std::list<Arc::XMLNode>::iterator it;
00083   bool found = false;
00084   for( it = class_config_list_.begin(); it != class_config_list_.end(); it++) {
00085     node = (*it);
00086     if((std::string)(node["PDPConfig"]["Evaluator"].Attribute("name")) == classname) { found = true; break; }
00087   }
00088   if(found) {
00089     bool has_covered = false;
00090     for(std::list<std::string>::iterator p = plugins.begin();p!=plugins.end();++p) {
00091       for(int i=0;;i++) {
00092         Arc::XMLNode cn = node["ModuleManager"]["Path"][i];
00093         if(!cn) break;
00094         if((std::string)(cn) == (*p)){ has_covered = true; break; }
00095       }
00096       if(!has_covered)
00097         node["ModuleManager"].NewChild("Path")=*p;
00098     }
00099   } else {
00100     // Loading unknown evaluator
00101     Arc::XMLNode cfg("\
00102       <ArcConfig\
00103        xmlns=\"http://www.nordugrid.org/schemas/ArcConfig/2007\">\
00104        <ModuleManager/>\
00105       </ArcConfig>");
00106     for(std::list<std::string>::iterator plugin = plugins.begin();plugin!=plugins.end();++plugin) {
00107       cfg["ModuleManager"].NewChild("Path")=*plugin;
00108       try {
00109         Glib::Dir dir(*plugin);
00110         for(Glib::DirIterator file = dir.begin(); file != dir.end(); file++) {
00111           std::string name = *file;
00112           if(name.substr(0, 3) != "lib") continue;
00113           std::size_t pos = name.rfind(".");
00114           std::string subname;
00115           if(pos!=std::string::npos) subname = name.substr(pos);
00116           if(subname != G_MODULE_SUFFIX) continue;
00117           std::string fname = Glib::build_filename(*plugin,name);
00118           // Few tests just in case
00119           if(!file_test(fname,Glib::FILE_TEST_IS_EXECUTABLE)) continue;
00120           if(!file_test(fname,Glib::FILE_TEST_IS_REGULAR | Glib::FILE_TEST_IS_SYMLINK)) continue;
00121           name = name.substr(3,name.find('.')-3);
00122           Arc::XMLNode plugcfg = cfg.NewChild("Plugins");
00123           plugcfg.NewAttribute("Name")=name;
00124           plugcfg.NewChild("Plugin").NewAttribute("Name")="__arc_evaluator_modules__";
00125         };
00126       } catch (Glib::FileError) {};
00127     }
00128     cfg.New(node);
00129   }
00130   Arc::Config modulecfg(node);
00131   classloader = Arc::ClassLoader::getClassLoader(&modulecfg);
00132   //Dynamically load Evaluator object according to configure information. 
00133   //It should be the caller to free the object
00134   eval = (Evaluator*)(classloader->Instance(classname, &node, "__arc_evaluator_modules__"));
00135 
00136   if(!eval) logger.msg(Arc::ERROR, "Can not load arc evaluator object: %s",classname); 
00137   return eval;
00138 }
00139 
00140 Evaluator* EvaluatorLoader::getEvaluator(const Policy* policy) {
00141   if(!policy) return NULL;
00142   return getEvaluator(policy->getEvalName());
00143 }
00144 
00145 Evaluator* EvaluatorLoader::getEvaluator(const Request* request) {
00146   if(!request) return NULL;
00147   return getEvaluator(request->getEvalName());
00148 }
00149 
00150 Request* EvaluatorLoader::getRequest(const std::string& classname, const Source& requestsource) {
00151   ArcSec::Request* req = NULL;
00152   Arc::ClassLoader* classloader = NULL;
00153   
00154   //Get the request node
00155   Arc::XMLNode reqnode = requestsource.Get();
00156 
00157   //Get the lib path from environment, and put it into the configuration xml node
00158   std::list<std::string> plugins = Arc::ArcLocation::GetPlugins();
00159 
00160   Arc::XMLNode node;
00161   std::list<Arc::XMLNode>::iterator it;
00162   bool found = false;
00163   for( it = class_config_list_.begin(); it != class_config_list_.end(); it++) {
00164     node = (*it);
00165     if((std::string)(node["PDPConfig"]["Request"].Attribute("name")) == classname) { found = true; break; }
00166   }
00167 
00168   if(found) {
00169     bool has_covered = false;
00170     for(std::list<std::string>::iterator p = plugins.begin();p!=plugins.end();++p) {
00171       for(int i=0;;i++) {
00172         Arc::XMLNode cn = node["ModuleManager"]["Path"][i];
00173         if(!cn) break;
00174         if((std::string)(cn) == (*p)){ has_covered = true; break; }
00175       }
00176       if(!has_covered)
00177         node["ModuleManager"].NewChild("Path")=*p;
00178     }
00179 
00180     Arc::Config modulecfg(node);
00181     classloader = Arc::ClassLoader::getClassLoader(&modulecfg);
00182     //Dynamically load Request object according to configure information. 
00183     //It should be the caller to free the object
00184     req = (Request*)(classloader->Instance(classname, &reqnode, "__arc_request_modules__"));
00185   }
00186   
00187   if(!req) logger.msg(Arc::ERROR, "Can not load arc request object: %s",classname); 
00188   return req;
00189 }
00190 
00191 Policy* EvaluatorLoader::getPolicy(const std::string& classname, const Source& policysource) {
00192   ArcSec::Policy* policy = NULL;
00193   Arc::ClassLoader* classloader = NULL;
00194 
00195   //Get policy node
00196   Arc::XMLNode policynode = policysource.Get();
00197 
00198   //Get the lib path from environment, and put it into the configuration xml node
00199   std::list<std::string> plugins = Arc::ArcLocation::GetPlugins();
00200 
00201   Arc::XMLNode node;
00202   std::list<Arc::XMLNode>::iterator it;
00203   bool found = false;
00204   for( it = class_config_list_.begin(); it != class_config_list_.end(); it++) {
00205     node = (*it);
00206     if((std::string)(node["PDPConfig"]["Policy"].Attribute("name")) == classname) { found = true; break; }
00207   }
00208 
00209   if(found) {
00210     bool has_covered = false;
00211     for(std::list<std::string>::iterator p = plugins.begin();p!=plugins.end();++p) {
00212       for(int i=0;;i++) {
00213         Arc::XMLNode cn = node["ModuleManager"]["Path"][i];
00214         if(!cn) break;
00215         if((std::string)(cn) == (*p)){ has_covered = true; break; }
00216       }
00217       if(!has_covered)
00218         node["ModuleManager"].NewChild("Path")=*p;
00219     }
00220 
00221     Arc::Config modulecfg(node);
00222     classloader = Arc::ClassLoader::getClassLoader(&modulecfg);
00223     //Dynamically load Policy object according to configure information. 
00224     //It should be the caller to free the object
00225     policy = (Policy*)(classloader->Instance(classname, &policynode, "__arc_policy_modules__"));
00226   }
00227 
00228   if(!policy) logger.msg(Arc::ERROR, "Can not load policy object: %s",classname); 
00229   return policy;
00230 }
00231 
00232 Policy* EvaluatorLoader::getPolicy(const Source& policysource) {
00233   ArcSec::Policy* policy = NULL;
00234   Arc::ClassLoader* classloader = NULL;
00235 
00236   //Get policy node
00237   Arc::XMLNode policynode = policysource.Get();
00238 
00239   //Get the lib path from environment, and put it into the configuration xml node
00240   std::list<std::string> plugins = Arc::ArcLocation::GetPlugins();
00241 
00242   Arc::XMLNode cfg("\
00243     <ArcConfig\
00244      xmlns=\"http://www.nordugrid.org/schemas/ArcConfig/2007\">\
00245      <ModuleManager/>\
00246     </ArcConfig>");
00247   for(std::list<std::string>::iterator plugin = plugins.begin();plugin!=plugins.end();++plugin) {
00248     cfg["ModuleManager"].NewChild("Path")=*plugin;
00249     try {
00250       Glib::Dir dir(*plugin);
00251       for(Glib::DirIterator file = dir.begin(); file != dir.end(); file++) {
00252         std::string name = *file;
00253         if(name.substr(0, 3) != "lib") continue;
00254          // TODO: This won't work on windows and maybe even on some
00255          // unices which do have shared libraries ending with .so
00256         if(name.substr(name.length()-3, 3) != ".so") continue;
00257         std::string fname = Glib::build_filename(*plugin,name);
00258         // Few tests just in case
00259         if(!file_test(fname,Glib::FILE_TEST_IS_EXECUTABLE)) continue;
00260         if(!file_test(fname,Glib::FILE_TEST_IS_REGULAR | Glib::FILE_TEST_IS_SYMLINK)) continue;
00261         name = name.substr(3,name.find('.')-3);
00262         Arc::XMLNode plugcfg = cfg.NewChild("Plugins");
00263         plugcfg.NewAttribute("Name")=name;
00264         plugcfg.NewChild("Plugin").NewAttribute("Name")="__arc_policy_modules__";
00265         // ?? plugcfg["Plugin"]="policy"; ??
00266       };
00267     } catch (Glib::FileError) {};
00268   };
00269 
00270   Arc::Config modulecfg(cfg);
00271   classloader = Arc::ClassLoader::getClassLoader(&modulecfg);
00272   //Dynamically load Policy object according to configure information. 
00273   //It should be the caller to free the object
00274   policy = (Policy*)(classloader->Instance(&policynode, "__arc_policy_modules__"));
00275 
00276   if(!policy) logger.msg(Arc::ERROR, "Can not load policy object"); 
00277   return policy;
00278 }
00279 
00280 Request* EvaluatorLoader::getRequest(const Source& requestsource) {
00281   ArcSec::Request* request = NULL;
00282   Arc::ClassLoader* classloader = NULL;
00283 
00284   //Get policy node
00285   Arc::XMLNode requestnode = requestsource.Get();
00286 
00287   //Get the lib path from environment, and put it into the configuration xml node
00288   std::list<std::string> plugins = Arc::ArcLocation::GetPlugins();
00289 
00290   Arc::XMLNode cfg("\
00291     <ArcConfig\
00292      xmlns=\"http://www.nordugrid.org/schemas/ArcConfig/2007\">\
00293      <ModuleManager/>\
00294     </ArcConfig>");
00295   for(std::list<std::string>::iterator plugin = plugins.begin();plugin!=plugins.end();++plugin) {
00296     cfg["ModuleManager"].NewChild("Path")=*plugin;
00297     try {
00298       Glib::Dir dir(*plugin);
00299       for(Glib::DirIterator file = dir.begin(); file != dir.end(); file++) {
00300         std::string name = *file;
00301         if(name.substr(0, 3) != "lib") continue;
00302          // TODO: This won't work on windows and maybe even on some
00303          // unices which do have shared libraries ending with .so
00304         if(name.substr(name.length()-3, 3) != ".so") continue;
00305         std::string fname = Glib::build_filename(*plugin,name);
00306         // Few tests just in case
00307         if(!file_test(fname,Glib::FILE_TEST_IS_EXECUTABLE)) continue;
00308         if(!file_test(fname,Glib::FILE_TEST_IS_REGULAR | Glib::FILE_TEST_IS_SYMLINK)) continue;
00309         name = name.substr(3,name.find('.')-3);
00310         Arc::XMLNode plugcfg = cfg.NewChild("Plugins");
00311         plugcfg.NewAttribute("Name")=name;
00312         plugcfg.NewChild("Plugin").NewAttribute("Name")="__arc_request_modules__";
00313         // ?? plugcfg["Plugin"]="request"; ??
00314       };
00315     } catch (Glib::FileError) {};
00316   };
00317 
00318   Arc::Config modulecfg(cfg);
00319   classloader = Arc::ClassLoader::getClassLoader(&modulecfg);
00320   //Dynamically load Request object according to configure information. 
00321   //It should be the caller to free the object
00322   request = (Request*)(classloader->Instance(&requestnode, "__arc_request_modules__"));
00323 
00324   if(!request) logger.msg(Arc::ERROR, "Can not load request object"); 
00325   return request;
00326 }
00327 
00328 }