Back to index

nordugrid-arc-nox  1.1.0~rc6
Public Member Functions | Private Attributes | Static Private Attributes
Arc::ClientX509Delegation Class Reference

#include <ClientX509Delegation.h>

Collaboration diagram for Arc::ClientX509Delegation:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 ClientX509Delegation ()
 Constructor creates MCC chain and connects to server.
 ClientX509Delegation (const BaseConfig &cfg, const URL &url)
virtual ~ClientX509Delegation ()
bool createDelegation (DelegationType deleg, std::string &delegation_id)
 Create the delegation credential according to the different remote delegation service.
bool destroyDelegation (DelegationType deleg)
bool acquireDelegation (DelegationType deleg, std::string &delegation_cred, std::string &delegation_id, const std::string cred_identity="", const std::string cred_delegator_ip="", const std::string username="", const std::string password="")
 Acquire delegation credential from delegation service.

Private Attributes

ClientSOAPsoap_client_
std::string cert_file_
std::string privkey_file_
std::string proxy_file_
std::string trusted_ca_dir_
std::string trusted_ca_file_
Credentialsigner_

Static Private Attributes

static Logger logger

Detailed Description

Definition at line 45 of file ClientX509Delegation.h.


Constructor & Destructor Documentation

Constructor creates MCC chain and connects to server.

Definition at line 48 of file ClientX509Delegation.h.

{}

Definition at line 25 of file ClientX509Delegation.cpp.

    : soap_client_(NULL),
      signer_(NULL) {
    soap_client_ = new ClientSOAP(cfg, url, 60);

    //Use the certificate and key in the main chain to delegate
    cert_file_ = cfg.cert;
    privkey_file_ = cfg.key;
    proxy_file_ = cfg.proxy;
    trusted_ca_dir_ = cfg.cadir;
    trusted_ca_file_ = cfg.cafile;
    if (!cert_file_.empty() && !privkey_file_.empty())
      signer_ = new Credential(cert_file_, privkey_file_, trusted_ca_dir_, trusted_ca_file_);
    else if (!proxy_file_.empty())
      signer_ = new Credential(proxy_file_, "", trusted_ca_dir_, trusted_ca_file_);
  }

Definition at line 43 of file ClientX509Delegation.cpp.

                                              {
    if (soap_client_)
      delete soap_client_;
    if (signer_)
      delete signer_;
  }

Member Function Documentation

bool Arc::ClientX509Delegation::acquireDelegation ( DelegationType  deleg,
std::string &  delegation_cred,
std::string &  delegation_id,
const std::string  cred_identity = "",
const std::string  cred_delegator_ip = "",
const std::string  username = "",
const std::string  password = "" 
)

Acquire delegation credential from delegation service.

This method should be called by intermediate service ('n+1' service as explained on above) in order to use this delegation credential on behalf of the EEC's holder.

Parameters:
delegDelegation type
delegation_iddelegation ID which is used to look up the credential by delegation service
cred_identitythe identity (in case of x509 credential, it is the DN of EEC credential).
cred_delegator_ipthe IP address of the credential delegator. Regard of delegation, an intermediate service should accomplish three tasks:
  1. Acquire 'n' level delegation credential (which is delegated by 'n-1' level delegator) from delegation service;
  2. Create 'n+1' level delegation credential to delegation service;
  3. Use 'n' level delegation credential to act on behalf of the EEC's holder. In case of absense of delegation_id, the 'n-1' level delegator's IP address and credential's identity are supposed to be used for look up the delegation credential from delegation service.

Definition at line 232 of file ClientX509Delegation.cpp.

                                                                                                   {
    if (deleg == DELEG_ARC) {
      //Use the DelegationInterface class for ARC delegation service
      logger.msg(INFO, "Getting delegation credential from ARC delegation service");
      if (soap_client_ != NULL) {
        NS ns;
        ns["deleg"] = ARC_DELEGATION_NAMESPACE;
        PayloadSOAP request(ns);
        XMLNode tokenlookup = request.NewChild("deleg:AcquireCredentials").NewChild("deleg:DelegatedTokenLookup");
        //Use delegation ID to acquire delegation credential from
        //delegation service, if the delegation ID is presented;
        if (!delegation_id.empty())
          tokenlookup.NewChild("deleg:Id") = delegation_id;
        //If delegation ID is not presented, use the credential identity
        //credential delegator's IP to acquire delegation credential
        else {
          tokenlookup.NewChild("deleg:CredIdentity") = cred_identity;
          tokenlookup.NewChild("deleg:CredDelegatorIP") = cred_delegator_ip;
        }
        //Generate a X509 request
        std::string x509req_str;
        Time start;
        int keybits = 1024;
        Credential cred_request(start, Period(), keybits);
        cred_request.GenerateRequest(x509req_str);
        tokenlookup.NewChild("deleg:Value") = x509req_str;
        std::string privkey_str;
        cred_request.OutputPrivatekey(privkey_str);

        PayloadSOAP *response = NULL;
        //Send AcquireCredentials request
        MCC_Status status = soap_client_->process(&request, &response);
        if (status != STATUS_OK) {
          logger.msg(ERROR, "DelegateCredentialsInit failed");
          return false;
        }
        if (!response) {
          logger.msg(ERROR, "There is no SOAP response");
          return false;
        }
        XMLNode token = (*response)["AcquireCredentialsResponse"]["DelegatedToken"];
        if (!token) {
          logger.msg(ERROR, "There is no Delegated X509 token in the response");
          delete response;
          return false;
        }
        if (((std::string)(token.Attribute("Format"))) != "x509") {
          logger.msg(ERROR, "There is no Format delegated token in the response");
          delete response;
          return false;
        }
        delegation_id = (std::string)(token["Id"]);
        std::string delegation_cert = (std::string)(token["Value"]);
        delete response;
        if (delegation_id.empty() || delegation_cert.empty()) {
          logger.msg(ERROR, "There is no Id or X509 token value in the response");
          return false;
        }

        Credential proxy_cred(delegation_cert, privkey_str, trusted_ca_dir_, trusted_ca_file_, "", false);
        proxy_cred.OutputCertificate(delegation_cred);
        proxy_cred.OutputPrivatekey(delegation_cred);
        proxy_cred.OutputCertificateChain(delegation_cred);

        logger.msg(DEBUG,"Get delegated credential from delegation service: \n %s",delegation_cred.c_str());
        return true;
      }
      else {
        logger.msg(ERROR, "There is no SOAP connection chain configured");
        return false;
      }
    }
    else {}
  }

Here is the call graph for this function:

Here is the caller graph for this function:

bool Arc::ClientX509Delegation::createDelegation ( DelegationType  deleg,
std::string &  delegation_id 
)

Create the delegation credential according to the different remote delegation service.

This method should be called by holder of EEC(end entity credential) which would delegate its EEC credential, or by holder of delegated credential(normally, the holder is intermediate service) which would further delegate the credential (on behalf of the original EEC's holder) (for instance, the 'n' intermediate service creates a delegation credential, then the 'n+1' intermediate service aquires this delegation credential from the delegation service and also acts on behalf of the EEC's holder by using this delegation credential).

Parameters:
delegDelegation type
delegation_idFor gridsite delegation service, the delegation_id is supposed to be created by client side, and sent to service side; for ARC delegation service, the delegation_id is supposed to be created by service side, and returned back. So for gridsite delegation service, this parameter is treated as input, while for ARC delegation service, it is treated as output.

Definition at line 50 of file ClientX509Delegation.cpp.

                                                                                            {

    if (deleg == DELEG_ARC) {
      //Use the DelegationInterface class for ARC delegation service
      logger.msg(INFO, "Creating delegation credential to ARC delegation service");
      if (soap_client_ != NULL) {
        NS ns;
        ns["deleg"] = ARC_DELEGATION_NAMESPACE;
        PayloadSOAP request(ns);
        request.NewChild("deleg:DelegateCredentialsInit");
        PayloadSOAP *response = NULL;
        //Send DelegateCredentialsInit request
        MCC_Status status = soap_client_->process(&request, &response);
        if (status != STATUS_OK) {
          logger.msg(ERROR, "DelegateCredentialsInit failed");
          return false;
        }
        if (!response) {
          logger.msg(ERROR, "There is no SOAP response");
          return false;
        }
        XMLNode token = (*response)["DelegateCredentialsInitResponse"]["TokenRequest"];
        if (!token) {
          logger.msg(ERROR, "There is no X509 request in the response");
          delete response;
          return false;
        }
        if (((std::string)(token.Attribute("Format"))) != "x509") {
          logger.msg(ERROR, "There is no Format request in the response");
          delete response;
          return false;
        }
        delegation_id = (std::string)(token["Id"]);
        std::string x509request = (std::string)(token["Value"]);
        delete response;
        if (delegation_id.empty() || x509request.empty()) {
          logger.msg(ERROR, "There is no Id or X509 request value in the response");
          return false;
        }

        //std::cout<<"X509 Request: \n"<<x509request<<std::endl;

        //Sign the proxy certificate
        Time start;
        Credential proxy(start, Period(12 * 3600), 0, "rfc", "inheritAll", "", -1);
        //Set proxy path length to be -1, which means infinit length
        std::string signedcert;
        proxy.InquireRequest(x509request);
        if (!(signer_->SignRequest(&proxy, signedcert))) {
          logger.msg(ERROR, "DelegateProxy failed");
          return false;
        }
        std::string signercert_str;
        std::string signercertchain_str;
        signer_->OutputCertificate(signercert_str);
        signer_->OutputCertificateChain(signercertchain_str);
        signedcert.append(signercert_str);
        signedcert.append(signercertchain_str);
        std::cout<<"X509 proxy certificate: \n"<<signedcert<<std::endl;

        PayloadSOAP request2(ns);
        XMLNode token2 = request2.NewChild("deleg:UpdateCredentials").NewChild("deleg:DelegatedToken");
        token2.NewAttribute("deleg:Format") = "x509";
        token2.NewChild("deleg:Id") = delegation_id;
        token2.NewChild("deleg:Value") = signedcert;
        //Send UpdateCredentials request
        status = soap_client_->process(&request2, &response);
        if (status != STATUS_OK) {
          logger.msg(ERROR, "UpdateCredentials failed");
          return false;
        }
        if (!response) {
          logger.msg(ERROR, "There is no SOAP response");
          return false;
        }
        if (!(*response)["UpdateCredentialsResponse"]) {
          logger.msg(ERROR, "There is no UpdateCredentialsResponse in response");
          delete response;
          return false;
        }
        delete response;
        return true;
      }
      else {
        logger.msg(ERROR, "There is no SOAP connection chain configured");
        return false;
      }
    }
    else if (deleg == DELEG_GRIDSITE) {
      //Move the current delegation related code in CREAMClient class to here
      logger.msg(INFO, "Creating delegation to CREAM delegation service");

      NS ns;
      ns["deleg"] = GS_DELEGATION_NAMESPACE;
      PayloadSOAP request(ns);
      XMLNode getProxyReqRequest = request.NewChild("deleg:getProxyReq");
      XMLNode delegid = getProxyReqRequest.NewChild("deleg:delegationID");
      delegid.Set(delegation_id);
      PayloadSOAP *response = NULL;
      //Send the getProxyReq request
      if (soap_client_) {
        MCC_Status status = soap_client_->process("", &request, &response);
        if (!status) {
          logger.msg(ERROR, "Delegation getProxyReq request failed");
          return false;
        }
        if (response == NULL) {
          logger.msg(ERROR, "There is no SOAP response");
          return false;
        }
      }
      else {
        logger.msg(ERROR, "There is no SOAP connection chain configured");
        return false;
      }
      std::string getProxyReqReturnValue;

      if ((bool)(*response) &&
          (bool)((*response)["getProxyReqResponse"]["getProxyReqReturn"]) &&
          ((std::string)(*response)["getProxyReqResponse"]["getProxyReqReturn"] != ""))
        getProxyReqReturnValue =
          (std::string)(*response)["getProxyReqResponse"]["getProxyReqReturn"];
      else {
        logger.msg(ERROR, "Creating delegation to CREAM delegation service failed");
        return false;
      }
      delete response;

      //Sign the proxy certificate
      Time start;
      //start = start - Period(300);
      Credential proxy(start);
      std::string signedcert;
      //std::cout<<"X509 Request: \n"<<getProxyReqReturnValue<<std::endl;
      proxy.InquireRequest(getProxyReqReturnValue);
      proxy.SetProxyPolicy("gsi2", "", "", -1);
      if (!(signer_->SignRequest(&proxy, signedcert))) {
        logger.msg(ERROR, "DelegateProxy failed");
        return false;
      }

      std::string signerstr, signerchain_str;
      signer_->OutputCertificate(signerstr);
      signer_->OutputCertificateChain(signerchain_str);
      signedcert.append(signerstr).append(signerchain_str);

      PayloadSOAP request2(ns);
      XMLNode putProxyRequest = request2.NewChild("deleg:putProxy");
      XMLNode delegid_node = putProxyRequest.NewChild("deleg:delegationID");
      delegid_node.Set(delegation_id);
      XMLNode proxy_node = putProxyRequest.NewChild("deleg:proxy");
      proxy_node.Set(signedcert);
      response = NULL;

      //Send the putProxy request
      if (soap_client_) {
        MCC_Status status = soap_client_->process("", &request2, &response);
        if (!status) {
          logger.msg(ERROR, "Delegation putProxy request failed");
          return false;
        }
        if (response == NULL) {
          logger.msg(ERROR, "There is no SOAP response");
          return false;
        }
      }
      else {
        logger.msg(ERROR, "There is no SOAP connection chain configured");
        return false;
      }

      if (!(bool)(*response) || !(bool)((*response)["putProxyResponse"])) {
        logger.msg(ERROR, "Creating delegation to CREAM delegation failed");
        return false;
      }
      delete response;
    }
    else if (deleg == DELEG_MYPROXY) {}

    return true;
  }

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 71 of file ClientX509Delegation.h.

                                                 {
      return false;
    }

Here is the caller graph for this function:


Member Data Documentation

Definition at line 104 of file ClientX509Delegation.h.

Definition at line 110 of file ClientX509Delegation.h.

Definition at line 105 of file ClientX509Delegation.h.

Definition at line 106 of file ClientX509Delegation.h.

Definition at line 109 of file ClientX509Delegation.h.

Definition at line 103 of file ClientX509Delegation.h.

Definition at line 107 of file ClientX509Delegation.h.

Definition at line 108 of file ClientX509Delegation.h.


The documentation for this class was generated from the following files: