Back to index

nordugrid-arc-nox  1.1.0~rc6
ClientX509Delegation.cpp
Go to the documentation of this file.
00001 // -*- indent-tabs-mode: nil -*-
00002 
00003 #ifdef HAVE_CONFIG_H
00004 #include <config.h>
00005 #endif
00006 
00007 // This define is needed to have maximal values for types with fixed size
00008 #define __STDC_LIMIT_MACROS
00009 #include <stdlib.h>
00010 #include <map>
00011 
00012 #include <arc/StringConv.h>
00013 #include <arc/URL.h>
00014 #include <arc/message/PayloadRaw.h>
00015 #include <arc/message/MCC.h>
00016 
00017 #include "ClientX509Delegation.h"
00018 
00019 namespace Arc {
00020   Logger ClientX509Delegation::logger(Logger::getRootLogger(), "ClientX509Delegation");
00021 
00022 #define ARC_DELEGATION_NAMESPACE "http://www.nordugrid.org/schemas/delegation"
00023 #define GS_DELEGATION_NAMESPACE "http://www.gridsite.org/namespaces/delegation-2"
00024 
00025   ClientX509Delegation::ClientX509Delegation(const BaseConfig& cfg,
00026                                              const URL& url)
00027     : soap_client_(NULL),
00028       signer_(NULL) {
00029     soap_client_ = new ClientSOAP(cfg, url, 60);
00030 
00031     //Use the certificate and key in the main chain to delegate
00032     cert_file_ = cfg.cert;
00033     privkey_file_ = cfg.key;
00034     proxy_file_ = cfg.proxy;
00035     trusted_ca_dir_ = cfg.cadir;
00036     trusted_ca_file_ = cfg.cafile;
00037     if (!cert_file_.empty() && !privkey_file_.empty())
00038       signer_ = new Credential(cert_file_, privkey_file_, trusted_ca_dir_, trusted_ca_file_);
00039     else if (!proxy_file_.empty())
00040       signer_ = new Credential(proxy_file_, "", trusted_ca_dir_, trusted_ca_file_);
00041   }
00042 
00043   ClientX509Delegation::~ClientX509Delegation() {
00044     if (soap_client_)
00045       delete soap_client_;
00046     if (signer_)
00047       delete signer_;
00048   }
00049 
00050   bool ClientX509Delegation::createDelegation(DelegationType deleg, std::string& delegation_id) {
00051 
00052     if (deleg == DELEG_ARC) {
00053       //Use the DelegationInterface class for ARC delegation service
00054       logger.msg(INFO, "Creating delegation credential to ARC delegation service");
00055       if (soap_client_ != NULL) {
00056         NS ns;
00057         ns["deleg"] = ARC_DELEGATION_NAMESPACE;
00058         PayloadSOAP request(ns);
00059         request.NewChild("deleg:DelegateCredentialsInit");
00060         PayloadSOAP *response = NULL;
00061         //Send DelegateCredentialsInit request
00062         MCC_Status status = soap_client_->process(&request, &response);
00063         if (status != STATUS_OK) {
00064           logger.msg(ERROR, "DelegateCredentialsInit failed");
00065           return false;
00066         }
00067         if (!response) {
00068           logger.msg(ERROR, "There is no SOAP response");
00069           return false;
00070         }
00071         XMLNode token = (*response)["DelegateCredentialsInitResponse"]["TokenRequest"];
00072         if (!token) {
00073           logger.msg(ERROR, "There is no X509 request in the response");
00074           delete response;
00075           return false;
00076         }
00077         if (((std::string)(token.Attribute("Format"))) != "x509") {
00078           logger.msg(ERROR, "There is no Format request in the response");
00079           delete response;
00080           return false;
00081         }
00082         delegation_id = (std::string)(token["Id"]);
00083         std::string x509request = (std::string)(token["Value"]);
00084         delete response;
00085         if (delegation_id.empty() || x509request.empty()) {
00086           logger.msg(ERROR, "There is no Id or X509 request value in the response");
00087           return false;
00088         }
00089 
00090         //std::cout<<"X509 Request: \n"<<x509request<<std::endl;
00091 
00092         //Sign the proxy certificate
00093         Time start;
00094         Credential proxy(start, Period(12 * 3600), 0, "rfc", "inheritAll", "", -1);
00095         //Set proxy path length to be -1, which means infinit length
00096         std::string signedcert;
00097         proxy.InquireRequest(x509request);
00098         if (!(signer_->SignRequest(&proxy, signedcert))) {
00099           logger.msg(ERROR, "DelegateProxy failed");
00100           return false;
00101         }
00102         std::string signercert_str;
00103         std::string signercertchain_str;
00104         signer_->OutputCertificate(signercert_str);
00105         signer_->OutputCertificateChain(signercertchain_str);
00106         signedcert.append(signercert_str);
00107         signedcert.append(signercertchain_str);
00108         std::cout<<"X509 proxy certificate: \n"<<signedcert<<std::endl;
00109 
00110         PayloadSOAP request2(ns);
00111         XMLNode token2 = request2.NewChild("deleg:UpdateCredentials").NewChild("deleg:DelegatedToken");
00112         token2.NewAttribute("deleg:Format") = "x509";
00113         token2.NewChild("deleg:Id") = delegation_id;
00114         token2.NewChild("deleg:Value") = signedcert;
00115         //Send UpdateCredentials request
00116         status = soap_client_->process(&request2, &response);
00117         if (status != STATUS_OK) {
00118           logger.msg(ERROR, "UpdateCredentials failed");
00119           return false;
00120         }
00121         if (!response) {
00122           logger.msg(ERROR, "There is no SOAP response");
00123           return false;
00124         }
00125         if (!(*response)["UpdateCredentialsResponse"]) {
00126           logger.msg(ERROR, "There is no UpdateCredentialsResponse in response");
00127           delete response;
00128           return false;
00129         }
00130         delete response;
00131         return true;
00132       }
00133       else {
00134         logger.msg(ERROR, "There is no SOAP connection chain configured");
00135         return false;
00136       }
00137     }
00138     else if (deleg == DELEG_GRIDSITE) {
00139       //Move the current delegation related code in CREAMClient class to here
00140       logger.msg(INFO, "Creating delegation to CREAM delegation service");
00141 
00142       NS ns;
00143       ns["deleg"] = GS_DELEGATION_NAMESPACE;
00144       PayloadSOAP request(ns);
00145       XMLNode getProxyReqRequest = request.NewChild("deleg:getProxyReq");
00146       XMLNode delegid = getProxyReqRequest.NewChild("deleg:delegationID");
00147       delegid.Set(delegation_id);
00148       PayloadSOAP *response = NULL;
00149       //Send the getProxyReq request
00150       if (soap_client_) {
00151         MCC_Status status = soap_client_->process("", &request, &response);
00152         if (!status) {
00153           logger.msg(ERROR, "Delegation getProxyReq request failed");
00154           return false;
00155         }
00156         if (response == NULL) {
00157           logger.msg(ERROR, "There is no SOAP response");
00158           return false;
00159         }
00160       }
00161       else {
00162         logger.msg(ERROR, "There is no SOAP connection chain configured");
00163         return false;
00164       }
00165       std::string getProxyReqReturnValue;
00166 
00167       if ((bool)(*response) &&
00168           (bool)((*response)["getProxyReqResponse"]["getProxyReqReturn"]) &&
00169           ((std::string)(*response)["getProxyReqResponse"]["getProxyReqReturn"] != ""))
00170         getProxyReqReturnValue =
00171           (std::string)(*response)["getProxyReqResponse"]["getProxyReqReturn"];
00172       else {
00173         logger.msg(ERROR, "Creating delegation to CREAM delegation service failed");
00174         return false;
00175       }
00176       delete response;
00177 
00178       //Sign the proxy certificate
00179       Time start;
00180       //start = start - Period(300);
00181       Credential proxy(start);
00182       std::string signedcert;
00183       //std::cout<<"X509 Request: \n"<<getProxyReqReturnValue<<std::endl;
00184       proxy.InquireRequest(getProxyReqReturnValue);
00185       proxy.SetProxyPolicy("gsi2", "", "", -1);
00186       if (!(signer_->SignRequest(&proxy, signedcert))) {
00187         logger.msg(ERROR, "DelegateProxy failed");
00188         return false;
00189       }
00190 
00191       std::string signerstr, signerchain_str;
00192       signer_->OutputCertificate(signerstr);
00193       signer_->OutputCertificateChain(signerchain_str);
00194       signedcert.append(signerstr).append(signerchain_str);
00195 
00196       PayloadSOAP request2(ns);
00197       XMLNode putProxyRequest = request2.NewChild("deleg:putProxy");
00198       XMLNode delegid_node = putProxyRequest.NewChild("deleg:delegationID");
00199       delegid_node.Set(delegation_id);
00200       XMLNode proxy_node = putProxyRequest.NewChild("deleg:proxy");
00201       proxy_node.Set(signedcert);
00202       response = NULL;
00203 
00204       //Send the putProxy request
00205       if (soap_client_) {
00206         MCC_Status status = soap_client_->process("", &request2, &response);
00207         if (!status) {
00208           logger.msg(ERROR, "Delegation putProxy request failed");
00209           return false;
00210         }
00211         if (response == NULL) {
00212           logger.msg(ERROR, "There is no SOAP response");
00213           return false;
00214         }
00215       }
00216       else {
00217         logger.msg(ERROR, "There is no SOAP connection chain configured");
00218         return false;
00219       }
00220 
00221       if (!(bool)(*response) || !(bool)((*response)["putProxyResponse"])) {
00222         logger.msg(ERROR, "Creating delegation to CREAM delegation failed");
00223         return false;
00224       }
00225       delete response;
00226     }
00227     else if (deleg == DELEG_MYPROXY) {}
00228 
00229     return true;
00230   }
00231 
00232   bool ClientX509Delegation::acquireDelegation(DelegationType deleg, std::string& delegation_cred, std::string& delegation_id,
00233                                                const std::string cred_identity, const std::string cred_delegator_ip,
00234                                                const std::string username, const std::string password) {
00235     if (deleg == DELEG_ARC) {
00236       //Use the DelegationInterface class for ARC delegation service
00237       logger.msg(INFO, "Getting delegation credential from ARC delegation service");
00238       if (soap_client_ != NULL) {
00239         NS ns;
00240         ns["deleg"] = ARC_DELEGATION_NAMESPACE;
00241         PayloadSOAP request(ns);
00242         XMLNode tokenlookup = request.NewChild("deleg:AcquireCredentials").NewChild("deleg:DelegatedTokenLookup");
00243         //Use delegation ID to acquire delegation credential from
00244         //delegation service, if the delegation ID is presented;
00245         if (!delegation_id.empty())
00246           tokenlookup.NewChild("deleg:Id") = delegation_id;
00247         //If delegation ID is not presented, use the credential identity
00248         //credential delegator's IP to acquire delegation credential
00249         else {
00250           tokenlookup.NewChild("deleg:CredIdentity") = cred_identity;
00251           tokenlookup.NewChild("deleg:CredDelegatorIP") = cred_delegator_ip;
00252         }
00253         //Generate a X509 request
00254         std::string x509req_str;
00255         Time start;
00256         int keybits = 1024;
00257         Credential cred_request(start, Period(), keybits);
00258         cred_request.GenerateRequest(x509req_str);
00259         tokenlookup.NewChild("deleg:Value") = x509req_str;
00260         std::string privkey_str;
00261         cred_request.OutputPrivatekey(privkey_str);
00262 
00263         PayloadSOAP *response = NULL;
00264         //Send AcquireCredentials request
00265         MCC_Status status = soap_client_->process(&request, &response);
00266         if (status != STATUS_OK) {
00267           logger.msg(ERROR, "DelegateCredentialsInit failed");
00268           return false;
00269         }
00270         if (!response) {
00271           logger.msg(ERROR, "There is no SOAP response");
00272           return false;
00273         }
00274         XMLNode token = (*response)["AcquireCredentialsResponse"]["DelegatedToken"];
00275         if (!token) {
00276           logger.msg(ERROR, "There is no Delegated X509 token in the response");
00277           delete response;
00278           return false;
00279         }
00280         if (((std::string)(token.Attribute("Format"))) != "x509") {
00281           logger.msg(ERROR, "There is no Format delegated token in the response");
00282           delete response;
00283           return false;
00284         }
00285         delegation_id = (std::string)(token["Id"]);
00286         std::string delegation_cert = (std::string)(token["Value"]);
00287         delete response;
00288         if (delegation_id.empty() || delegation_cert.empty()) {
00289           logger.msg(ERROR, "There is no Id or X509 token value in the response");
00290           return false;
00291         }
00292 
00293         Credential proxy_cred(delegation_cert, privkey_str, trusted_ca_dir_, trusted_ca_file_, "", false);
00294         proxy_cred.OutputCertificate(delegation_cred);
00295         proxy_cred.OutputPrivatekey(delegation_cred);
00296         proxy_cred.OutputCertificateChain(delegation_cred);
00297 
00298         logger.msg(DEBUG,"Get delegated credential from delegation service: \n %s",delegation_cred.c_str());
00299         return true;
00300       }
00301       else {
00302         logger.msg(ERROR, "There is no SOAP connection chain configured");
00303         return false;
00304       }
00305     }
00306     else {}
00307   }
00308 
00309 
00310 } // namespace Arc