Back to index

nordugrid-arc-nox  1.1.0~rc6
DelegationCollector.cpp
Go to the documentation of this file.
00001 #ifdef HAVE_CONFIG_H
00002 #include <config.h>
00003 #endif
00004 
00005 #include <openssl/ssl.h>
00006 #include <openssl/x509v3.h>
00007 
00008 #include "PayloadTLSStream.h"
00009 #include "DelegationSecAttr.h"
00010 
00011 #include "DelegationCollector.h"
00012 
00013 namespace ArcSec {
00014 
00015 using namespace Arc;
00016 
00017 static Arc::Logger logger(Arc::Logger::getRootLogger(),"DelegationCollector");
00018 
00019 DelegationCollector::DelegationCollector(Config *cfg):SecHandler(cfg) {
00020 }
00021 
00022 DelegationCollector::~DelegationCollector(void) {
00023 }
00024 
00025 
00026 // TODO: In a future accept and store ALL policies. Let it fail at PDP level.
00027 //       Currently code fails immediately if policy not recognized.
00028 //       Alternatively behavior may be configurable.
00029 static bool get_proxy_policy(X509* cert,DelegationMultiSecAttr* sattr) {
00030   bool result = false;
00031 #ifdef HAVE_OPENSSL_PROXY
00032   PROXY_CERT_INFO_EXTENSION *pci = (PROXY_CERT_INFO_EXTENSION*)X509_get_ext_d2i(cert,NID_proxyCertInfo,NULL,NULL);
00033   if(!pci) return true; // No proxy 
00034   switch (OBJ_obj2nid(pci->proxyPolicy->policyLanguage)) {
00035     case NID_Independent: { // No rights granted
00036       // Either such situation should be disallowed or 
00037       // policy should be generated which granst no right for enything.
00038       // First option is easier to implement so using it at least yet.
00039       logger.msg(DEBUG,"Independent proxy - no rights granted");
00040     }; break; 
00041     case NID_id_ppl_inheritAll: {
00042       // All right granted. No additional policies should be enforced.
00043       logger.msg(DEBUG,"Proxy with all rights inherited");
00044       result=true;
00045     }; break;
00046     case NID_id_ppl_anyLanguage: { // Here we store ARC policy
00047       // Either this is ARC policy is determined by examining content
00048       const char* policy_str = (const char *)(pci->proxyPolicy->policy->data);
00049       int policy_length = pci->proxyPolicy->policy->length;
00050       if((policy_str == NULL) || (policy_length <= 0)) {
00051         logger.msg(DEBUG,"Proxy with empty policy  - fail on unrecognized policy");
00052         break;
00053       };
00054       {
00055         std::string s(policy_str,policy_length);
00056         logger.msg(DEBUG,"Proxy with specific policy: %s",s);
00057       };
00058       result = sattr->Add(policy_str,policy_length);
00059       if(result) {
00060         logger.msg(DEBUG,"Proxy with ARC Policy");
00061       } else {
00062         logger.msg(DEBUG,"Proxy with unknown policy  - fail on unrecognized policy");
00063       };
00064     };
00065     default: {
00066       // Unsupported policy - fail
00067     }; break;
00068   };
00069   PROXY_CERT_INFO_EXTENSION_free(pci);
00070 #endif
00071   return result;
00072 }
00073 
00074 bool DelegationCollector::Handle(Arc::Message* msg) const {
00075   DelegationMultiSecAttr* sattr = NULL;
00076   try {
00077     MessagePayload* mpayload = msg->Payload();
00078     if(!mpayload) return false; // No payload in this message
00079     PayloadTLSStream* tstream = dynamic_cast<PayloadTLSStream*>(msg->Payload());
00080     // Currently only TLS payloads are supported
00081     if(!tstream) return false;
00082     SecAttr* sattr_ = msg->Auth()->get("DELEGATION POLICY");
00083     if(sattr_) sattr=dynamic_cast<DelegationMultiSecAttr*>(sattr_);
00084     if(!sattr) sattr=new DelegationMultiSecAttr;
00085     X509* cert = tstream->GetPeerCert();
00086     if (cert != NULL) {
00087       if(!get_proxy_policy(cert,sattr)) {
00088         X509_free(cert);
00089         throw std::exception();
00090       };
00091       X509_free(cert);
00092     };
00093     STACK_OF(X509)* peerchain = tstream->GetPeerChain();
00094     if(peerchain != NULL) {
00095       for(int idx = 0;;++idx) {
00096         if(idx >= sk_X509_num(peerchain)) break;
00097         X509* cert = sk_X509_value(peerchain,idx);
00098         if(cert) {
00099           if(!get_proxy_policy(cert,sattr)) throw std::exception();
00100         };
00101       };
00102     };
00103     if(!sattr_) msg->Auth()->set("DELEGATION POLICY",sattr);
00104     return true;
00105   } catch(std::exception&) { };
00106   if(sattr) delete sattr;
00107   return false;
00108 }
00109 
00110 
00111 Arc::Plugin* DelegationCollector::get_sechandler(Arc::PluginArgument* arg) {
00112     ArcSec::SecHandlerPluginArgument* shcarg =
00113             arg?dynamic_cast<ArcSec::SecHandlerPluginArgument*>(arg):NULL;
00114     if(!shcarg) return NULL;
00115     return new DelegationCollector((Arc::Config*)(*shcarg));
00116 }
00117 
00118 }
00119 
00120 //Arc::PluginDescriptor PLUGINS_TABLE_NAME[] = {
00121 //    { "delegation.collector", "HED:SHC", 0, &ArcSec::DelegationCollector::get_sechandler},
00122 //    { NULL, NULL, 0, NULL }
00123 //};
00124