Back to index

nordugrid-arc-nox  1.1.0~rc6
IdentityMap.cpp
Go to the documentation of this file.
00001 #ifdef HAVE_CONFIG_H
00002 #include <config.h>
00003 #endif
00004 
00005 #include <fstream>
00006 #include <vector>
00007 
00008 #include <arc/Logger.h>
00009 #include <arc/StringConv.h>
00010 #include <arc/message/MCCLoader.h>
00011 
00012 #include "SimpleMap.h"
00013 
00014 #include "IdentityMap.h"
00015 
00016 static Arc::Plugin* get_sechandler(Arc::PluginArgument* arg) {
00017     ArcSec::SecHandlerPluginArgument* shcarg =
00018             arg?dynamic_cast<ArcSec::SecHandlerPluginArgument*>(arg):NULL;
00019     if(!shcarg) return NULL;
00020     return new ArcSec::IdentityMap((Arc::Config*)(*shcarg),(Arc::ChainContext*)(*shcarg));
00021 }
00022 
00023 Arc::PluginDescriptor PLUGINS_TABLE_NAME[] = {
00024     { "identity.map", "HED:SHC", 0, &get_sechandler},
00025     { NULL, NULL, 0, NULL }
00026 };
00027 
00028 namespace ArcSec {
00029 
00030 // --------------------------------------------------------------------------
00031 class LocalMapDirect: public LocalMap {
00032  private:
00033   std::string id_;
00034  public:
00035   LocalMapDirect(const std::string& id):id_(id) {};
00036   virtual ~LocalMapDirect(void) {};
00037   virtual std::string ID(Arc::Message*) { return id_; };
00038 };
00039 
00040 // --------------------------------------------------------------------------
00041 class LocalMapPool: public LocalMap {
00042  private:
00043   std::string dir_;
00044  public:
00045   LocalMapPool(const std::string& dir);
00046   virtual ~LocalMapPool(void);
00047   virtual std::string ID(Arc::Message* msg);
00048 };
00049 
00050 LocalMapPool::LocalMapPool(const std::string& dir):dir_(dir) {
00051 }
00052 
00053 LocalMapPool::~LocalMapPool(void) {
00054 }
00055 
00056 std::string LocalMapPool::ID(Arc::Message* msg) {
00057   // Get user Grid identity.
00058   // So far only DN from TLS is supported.
00059   std::string dn = msg->Attributes()->get("TLS:IDENTITYDN");
00060   if(dn.empty()) return "";
00061   SimpleMap pool(dir_);
00062   if(!pool) return "";
00063   return pool.map(dn);
00064 }
00065 
00066 // --------------------------------------------------------------------------
00067 class LocalMapList: public LocalMap {
00068  private:
00069   std::vector<std::string> files_;
00070  public:
00071   LocalMapList(const std::vector<std::string>& files);
00072   LocalMapList(const std::string& file);
00073   virtual ~LocalMapList(void);
00074   virtual std::string ID(Arc::Message* msg);
00075 };
00076 
00077 LocalMapList::LocalMapList(const std::vector<std::string>& files):files_(files) {
00078 }
00079 
00080 LocalMapList::LocalMapList(const std::string& file) {
00081     files_.push_back(file);
00082 }
00083 
00084 LocalMapList::~LocalMapList(void) {
00085 }
00086 
00087 static std::string get_val(std::string& str) {
00088   std::string val;
00089   if(str[0] == '"') {
00090     std::string::size_type p = str.find('"',1);
00091     if(p == std::string::npos) return "";
00092     val=str.substr(1,p-1);
00093     str=str.substr(p+1);
00094     return val;
00095   };
00096   if(str[0] == '\'') {
00097     std::string::size_type p = str.find('\'',1);
00098     if(p == std::string::npos) return "";
00099     val=str.substr(1,p-1);
00100     str=str.substr(p+1);
00101     return val;
00102   };
00103   std::string::size_type p = str.find_first_of(" \t");
00104   if(p == std::string::npos) {
00105     val=str; str.resize(0);
00106   } else {
00107     val=str.substr(0,p); str=str.substr(p);
00108   };
00109   return val;
00110 }
00111 
00112 std::string LocalMapList::ID(Arc::Message* msg) {
00113   // Compare user Grid identity to list in file.
00114   // So far only DN from TLS is supported.
00115   std::string dn = msg->Attributes()->get("TLS:IDENTITYDN");
00116   if(dn.empty()) return "";
00117   for (std::vector<std::string>::iterator it = files_.begin(); it != files_.end(); it++) {
00118     std::string file_ = *it;
00119     std::ifstream f(file_.c_str());
00120     if(!f.is_open() ) continue;
00121     for(;!f.eof();) {
00122       std::string buf;
00123       std::getline(f,buf);
00124       buf=Arc::trim(buf);
00125       if(buf.empty()) continue;
00126       if(buf[0] == '#') continue;
00127       std::string val = get_val(buf);
00128       if(val != dn) continue;
00129       buf=Arc::trim(buf);
00130       val=get_val(buf);
00131       if(val.empty()) continue;
00132       f.close();
00133       return val;
00134     };
00135     f.close();
00136   }
00137   return "";
00138 }
00139 
00140 // --------------------------------------------------------------------------
00141 static LocalMap* MakeLocalMap(Arc::XMLNode pdp) {
00142   Arc::XMLNode p;
00143   p=pdp["LocalName"];
00144   if(p) {
00145     std::string name = p;
00146     if(name.empty()) return NULL;
00147     return new LocalMapDirect(name);
00148   };
00149   p=pdp["LocalList"];
00150   if(p) {
00151     std::vector<std::string> files;
00152     while (p) {
00153         files.push_back((std::string) p);
00154         ++p;
00155     }
00156     if(files.empty()) return NULL;
00157     return new LocalMapList(files);
00158   };
00159   p=pdp["LocalSimplePool"];
00160   if(p) {
00161     std::string dir = p;
00162     if(dir.empty()) return NULL;
00163     return new LocalMapPool(dir);
00164   };
00165   return NULL;
00166 }
00167 
00168 // ---------------------------------------------------------------------------
00169 IdentityMap::IdentityMap(Arc::Config *cfg,Arc::ChainContext* ctx):ArcSec::SecHandler(cfg){
00170   Arc::PluginsFactory* pdp_factory = (Arc::PluginsFactory*)(*ctx);
00171   if(pdp_factory) {
00172     Arc::XMLNode plugins = (*cfg)["Plugins"];
00173     for(int n = 0;;++n) {
00174       Arc::XMLNode p = plugins[n];
00175       if(!p) break;
00176       std::string name = p["Name"];
00177       if(name.empty()) continue; // Nameless plugin?
00178       pdp_factory->load(name,PDPPluginKind);
00179     };
00180     Arc::XMLNode pdps = (*cfg)["PDP"];
00181     for(int n = 0;;++n) {
00182       Arc::XMLNode p = pdps[n];
00183       if(!p) break;
00184       std::string name = p.Attribute("name");
00185       if(name.empty()) continue; // Nameless?
00186       LocalMap* local_id = MakeLocalMap(p);
00187       if(!local_id) continue; // No mapping?
00188       Arc::Config cfg_(p);
00189       PDPPluginArgument arg(&cfg_);
00190       ArcSec::PDP* pdp = pdp_factory->GetInstance<PDP>(PDPPluginKind,name,&arg);
00191       if(!pdp) {
00192         delete local_id;
00193         logger.msg(Arc::ERROR, "PDP: %s can not be loaded", name);
00194         continue;
00195       };
00196       map_pair_t m;
00197       m.pdp=pdp;
00198       m.uid=local_id;
00199       maps_.push_back(m);
00200     };
00201   };
00202 }
00203 
00204 IdentityMap::~IdentityMap(void) {
00205   for(std::list<map_pair_t>::iterator p = maps_.begin();p!=maps_.end();++p) {
00206     if(p->pdp) delete p->pdp;
00207     if(p->uid) delete p->uid;
00208   };
00209 }
00210 
00211 bool IdentityMap::Handle(Arc::Message* msg) const {
00212   for(std::list<map_pair_t>::const_iterator p = maps_.begin();p!=maps_.end();++p) {
00213     if(p->pdp->isPermitted(msg)) {
00214       std::string id = p->uid->ID(msg);
00215       logger.msg(Arc::INFO,"Grid identity is mapped to local identity '%s'",id);
00216       msg->Attributes()->set("SEC:LOCALID",id);
00217       return true;  
00218     };
00219   }
00220   return true;
00221 }
00222 
00223 }
00224